npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

swc-plugin-auto-import

v0.0.7

Published

SWC plugin for auto importing APIs on-demand, inspired by unplugin-auto-import

Readme

SWC Auto Import Plugin

An SWC plugin similar to unplugin-auto-import that automatically imports APIs without manually writing import statements.

🚀 Features

  • ✨ Auto import APIs from popular frameworks (Vue, React, Vue Router, etc.)
  • 🎯 Support for custom import configuration
  • 🔍 Smart detection: avoids duplicate imports and local declarations
  • ⚡ Compile-time transformation with zero runtime overhead
  • 🛠️ Native TypeScript support

📦 Installation

npm install swc-plugin-auto-import
# or
yarn add swc-plugin-auto-import
# or
pnpm add swc-plugin-auto-import

🔧 Configuration

Configure in .swcrc

{
  "jsc": {
    "experimental": {
      "plugins": [
        [
          "swc-plugin-auto-import",
          {
            "imports": [
              "vue",
              "react",
              {
                "@vueuse/core": ["useMouse", "useFetch"]
              },
              {
                "from": "axios",
                "imports": [["default", "axios"]]
              }
            ],
            "debug": false
          }
        ]
      ]
    }
  }
}

Usage with Next.js

// next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      [
        'swc-plugin-auto-import',
        {
          imports: [
            'react',
            {
              'lodash-es': ['debounce', 'throttle'],
            },
          ],
        },
      ],
    ],
  },
}

Usage with Rspack

// rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            experimental: {
              plugins: [
                [
                  'swc-plugin-auto-import',
                  {
                    imports: ['react'],
                  },
                ],
              ],
            },
          },
        },
      },
    ],
  },
}

📋 Import Types Summary

The plugin supports four types of imports:

| Import Type | Mapping Format | Explicit Format | Generated Code | | -------------------- | ---------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------- | | Named | "ref" | { "name": "ref", "from": "vue" } | import { ref } from 'vue' | | Named with Alias | ["useFetch", "useMyFetch"] | { "name": "useFetch", "as": "useMyFetch", "from": "@vueuse/core" } | import { useFetch as useMyFetch } from '@vueuse/core' | | Default | ["default", "axios"] | { "name": "default", "as": "axios", "from": "axios" } | import axios from 'axios' | | Namespace | ["*", "_"] | { "name": "*", "as": "_", "from": "lodash" } | import * as _ from 'lodash' |

📖 Usage Examples

Vue 3 Auto Import

Configuration:

{
  "imports": ["vue"]
}

Input:

const count = ref(0)
const doubled = computed(() => count.value * 2)

onMounted(() => {
  console.log('Component mounted')
})

Output:

import { ref, computed, onMounted } from 'vue'

const count = ref(0)
const doubled = computed(() => count.value * 2)

onMounted(() => {
  console.log('Component mounted')
})

React Hooks Auto Import

Configuration:

{
  "imports": ["react"]
}

Input:

const [count, setCount] = useState(0)

useEffect(() => {
  console.log(count)
}, [count])

Output:

import { useState, useEffect } from 'react'

const [count, setCount] = useState(0)

useEffect(() => {
  console.log(count)
}, [count])

Custom Library Import

Configuration (using package mapping):

{
  "imports": [
    {
      "@vueuse/core": ["useMouse", "useKeyboard"]
    },
    {
      "lodash-es": ["debounce", "throttle"]
    }
  ]
}

Configuration (using explicit import array):

{
  "imports": [
    [
      { "name": "useMouse", "from": "@vueuse/core" },
      { "name": "useKeyboard", "from": "@vueuse/core" },
      { "name": "debounce", "from": "lodash-es" },
      { "name": "throttle", "from": "lodash-es" },
      { "name": "default", "as": "axios", "from": "axios" }
    ]
  ]
}

Input:

const { x, y } = useMouse()
const debouncedFn = debounce(() => {}, 300)

axios.get('/api/data')

Output:

import { useMouse } from '@vueuse/core'
import axios from 'axios'
import { debounce } from 'lodash-es'

const { x, y } = useMouse()
const debouncedFn = debounce(() => {}, 300)

axios.get('/api/data')

⚙️ Configuration Options

imports

Type: Arrayable<ImportsMap | PresetName | InlinePreset>
Default: undefined

Where:

  • Arrayable<T> = T | Array<T> - Can be a single value or an array
  • ImportsMap - Object mapping packages to their exports
  • PresetName - String like "react", "vue", etc.
  • InlinePreset - Object with from and imports fields

Import configuration. Supports multiple formats:

1. Preset String (Built-in presets)

{
  "imports": "react"
}

Or as an array:

{
  "imports": ["vue", "react", "vue-router", "react-router"]
}

Currently supported presets:

  • "vue" - Vue 3 Composition API
  • "react" - React Hooks
  • "react-dom" - React DOM APIs
  • "vue-router" - Vue Router Composition API
  • "react-router" - React Router Hooks

2. ImportsMap - Package Mapping Object

A simplified syntax for defining imports. Each key is a package name, and the value is an array of imports.

{
  "imports": {
    "package-name": [
      "namedExport",
      ["exportName", "alias"],
      ["default", "defaultName"],
      ["*", "namespace"]
    ]
  }
}

Example:

{
  "imports": {
    "@vueuse/core": ["useMouse", ["useFetch", "useMyFetch"]],
    "axios": [["default", "axios"]],
    "lodash": [["*", "_"]]
  }
}

Generated imports:

import { useFetch as useMyFetch, useMouse } from '@vueuse/core'
import axios from 'axios'
import * as _ from 'lodash'

Format explanation:

  • Named import: "useMouse"import { useMouse } from '@vueuse/core'
  • Named import with alias: ["useFetch", "useMyFetch"]import { useFetch as useMyFetch } from '@vueuse/core'
  • Default import: ["default", "axios"]import axios from 'axios'
  • Namespace import: ["*", "_"]import * as _ from 'lodash'

3. InlinePreset - Inline Import Configuration

An object with from field specifying the module and imports array:

{
  "imports": {
    "from": "react",
    "imports": ["useState", "useEffect", ["useMemo", "useMemoized"]]
  }
}

Generated imports:

import { useEffect, useMemo as useMemoized, useState } from 'react'

The imports array can contain:

  • String: "useState" - simple named import
  • Tuple: ["useMemo", "useMemoized"] - named import with alias
  • Object: { "name": "useEffect", "as": "useReactEffect" } - named import with optional alias
  • Nested InlinePreset: Another InlinePreset object for grouping

Example with nested presets:

{
  "imports": {
    "from": "react",
    "imports": [
      "useState",
      {
        "from": "react-dom",
        "imports": ["createPortal", "flushSync"]
      }
    ]
  }
}

Generated imports:

import { useState } from 'react'
import { createPortal, flushSync } from 'react-dom'

4. Explicit Import Array (Legacy)

An array of import items where each item specifies the name, optional as (alias), and from (package) fields:

{
  "imports": [
    [
      { "name": "ref", "from": "vue" },
      { "name": "useState", "as": "useSignal", "from": "react" },
      { "name": "default", "as": "_", "from": "lodash" },
      { "name": "*", "as": "lodash", "from": "lodash-es" }
    ]
  ]
}

Generated imports:

import _ from 'lodash'
import * as lodash from 'lodash-es'
import { useState as useSignal } from 'react'
import { ref } from 'vue'

Format explanation:

  • Named import: { "name": "ref", "from": "vue" }import { ref } from 'vue'
  • Named import with alias: { "name": "useState", "as": "useSignal", "from": "react" }import { useState as useSignal } from 'react'
  • Default import: { "name": "default", "as": "_", "from": "lodash" }import _ from 'lodash'
  • Namespace import: { "name": "*", "as": "lodash", "from": "lodash-es" }import * as lodash from 'lodash-es'

Mixed Format

You can combine all formats in an array:

{
  "imports": [
    "react",
    "react-dom",
    {
      "@vueuse/core": ["useMouse", "useFetch"]
    },
    {
      "from": "axios",
      "imports": [["default", "axios"]]
    },
    [{ "name": "computed", "from": "vue" }]
  ]
}

debug

Type: boolean
Default: false

Enable debug mode (reserved field in current version).

📋 Built-in Presets

Vue Preset

ref, computed, reactive, watch, watchEffect, onMounted, onUnmounted,
onBeforeMount, onBeforeUnmount, onUpdated, onBeforeUpdate, nextTick,
defineComponent, createApp, toRef, toRefs, unref, isRef

React Preset

useState, useEffect, useContext, useReducer, useCallback, useMemo,
useRef, useLayoutEffect, useImperativeHandle

Vue Router Preset

useRouter, useRoute

React Router Preset

useNavigate, useLocation, useParams, useSearchParams

🎯 Smart Features

1. No Duplicate Imports

If an API is already imported, the plugin won't add it again:

// Input
import { ref } from 'vue'
const count = ref(0)

// Output - unchanged
import { ref } from 'vue'
const count = ref(0)

2. No Import for Local Declarations

If an identifier is locally declared, the plugin won't add an import:

// Input
function ref() {
  return 'local ref'
}
const data = ref()

// Output - unchanged, no import added
function ref() {
  return 'local ref'
}
const data = ref()

🔄 Comparison with unplugin-auto-import

| Feature | unplugin-auto-import | swc-auto-import | | ------------------ | -------------------- | --------------- | | Runtime | Vite/Webpack/Rollup | SWC Compiler | | Performance | Fast | Very Fast | | .d.ts Generation | ✅ | Planned | | TypeScript Support | ✅ | ✅ | | Custom Resolvers | ✅ | Planned | | ESLint Integration | ✅ | Planned |

🛠️ Development

Build Plugin

# Build WASM plugin
cargo build-wasip1 --release

# Run tests
cargo test

Project Structure

swc-plugin-auto-import/
├── src/
│   ├── lib.rs          # Plugin source
│   ├── config.rs       # Configuration
│   ├── presets.rs      # Presets
│   ├── collector.rs    # Identifier collector
│   └── visitor.rs      # AST visitor
├── Cargo.toml          # Rust configuration
├── package.json        # npm package config
└── README.md           # Documentation

📝 How It Works

  1. Scanning Phase: Traverse AST to collect used, imported, and declared identifiers
  2. Matching Phase: Find identifiers that need auto-import based on presets and custom config
  3. Filtering Phase: Exclude already imported and locally declared identifiers
  4. Insertion Phase: Insert generated import statements at the top of the module

🤝 Contributing

Issues and Pull Requests are welcome!

📄 License

ISC License

🔗 Links