# @mikrojs/analyze-imports

> ESM import analyzer for Mikro.js bundling

Latest version **0.22.0** (published 2026-09-30) · MIT license · 0 weekly downloads

## Install

```sh
npm install @mikrojs/analyze-imports
pnpm add @mikrojs/analyze-imports
yarn add @mikrojs/analyze-imports
bun add @mikrojs/analyze-imports
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.22.0 |
| Published | 2026-09-30 |
| First published | 2026-04-25 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Node | >=24.0.0 |
| Dependencies | 3 |
| Unpacked size | 126.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 16 |
| Author | Bjørge Næss <bjoerge@gmail.com> |
| Maintainers | bjoerge |
| Keywords | analyzer, esm, imports, mikrojs |

## Links

- npm: https://www.npmjs.com/package/@mikrojs/analyze-imports
- Repository: https://github.com/mikrojs/mikro
- Homepage: https://github.com/mikrojs/mikro#readme
- Issues: https://github.com/mikrojs/mikro/issues
- npm.io page: https://npm.io/package/@mikrojs/analyze-imports

## Dependencies (3)

- [acorn](https://npm.io/package/acorn.md) ^8.18.0
- [estree-walker](https://npm.io/package/estree-walker.md) ^3.0.3
- [@sveltejs/acorn-typescript](https://npm.io/package/@sveltejs/acorn-typescript.md) ^1.0.13

## Recent versions

- 0.22.0 (latest) — 2026-09-30
- 0.21.1-next.20260928214050 (next) — 2026-09-28
- 0.21.0-pr-431.20260921210123 (pr-431) — 2026-09-21
- 0.19.0-pr-352.20260829215534 (pr-352) — 2026-08-29
- 0.18.0-pr-306.20260731215718 (pr-306) — 2026-07-31
- 0.17.1-pr-300.20260731010039 (pr-300) — 2026-07-31
- 0.17.0-pr-276.20260721233726 (pr-276) — 2026-07-21
- 0.16.1-pr-265.20260718161156 (pr-265) — 2026-07-18
- 0.15.0-pr-243.20260613121220 (pr-243) — 2026-06-13
- 0.14.0-pr-229.20260613004639 (pr-229) — 2026-06-13
- 0.11.0-pr-172.g462f877 (pr-172) — 2026-05-30
- 0.10.0-pr-171.g56c9fcc (pr-171) — 2026-05-30
- 0.10.0-pr-134.gc6ec955 (pr-134) — 2026-05-30
- 0.8.0-pr-133.g02588d5 (pr-133) — 2026-05-21
- 0.8.0-pr-115.g87a99f9 (pr-115) — 2026-05-16
- … 73 more at https://npm.io/package/@mikrojs/analyze-imports/versions

## README

### Import tracer for Mikro.js builds

`traceImports` follows the imports of an app's entry files. It returns the files
that deploy to the device, the path each one deploys to, and the import
specifiers the build has to replace in it.

```ts
import {readFile} from 'node:fs/promises'

import {applyRewrites, traceImports} from '@mikrojs/analyze-imports'

const {files, externals, duplicatePackages, problems} = await traceImports(['app/main.ts'], {
  deployDir: 'app',
  isExternal: (specifier) => specifier.startsWith('mikro/'),
})

for (const [deployPath, file] of files) {
  const contents =
    'contents' in file
      ? file.contents
      : applyRewrites(await readFile(file.source, 'utf-8'), file.rewrites)
  // write `contents` to `deployPath`
}
```

`traceImports` only reads. It reports what it cannot deploy in `problems`
(an import that does not resolve, a file that does not parse, a CommonJS
package, a file outside the app) and throws only when the file system does.

The result has four fields:

- `files` maps each deploy path to `{source, rewrites}`: the real file to read,
  and the ranges in it to replace. A file the trace generates has `{contents}`.
- `externals` maps each specifier that `isExternal` accepted to `static` or
  `dynamic`. A specifier is `dynamic` when no file imports it statically.
- `duplicatePackages` lists every package name that deploys in more than one
  directory, with the path and version of each copy.
- `problems` is a list of messages. An empty list means the files can deploy.

Entries that are relative paths are relative to the working directory. `root`
(the app directory, by default the working directory) decides which files are
the app's own. Pass `fs` to trace a tree that is not on disk; the tests do.

#### Where files deploy

Imports are resolved on the host the way Node resolves ESM: `exports`,
conditions, wildcard patterns, `#imports`, self-reference, and symlinks. Each
resolved import is then rewritten to a relative path, so the device never looks
a package up by name.

An app file keeps its path. A package deploys once, at `node_modules/<name>/`,
however many paths lead to it. When the app uses several packages with one name
(two versions, usually), the copy that the app's own files import keeps
`node_modules/<name>/`, and each other copy deploys at
`node_modules/<name>@<version>/`.

A package at `node_modules/<name>/` also gets a generated `package.json`. Its
`exports` map the subpaths the app imports to the deployed files, so that the
REPL can `import('<name>')`. A `<name>@<version>` directory gets none, and
cannot be imported by name. A package's own `package.json`
deploys only when something imports it, and then as `_package.json`.

`deployDir` is the directory, relative to `root`, that becomes the root of the
device's file system. A file outside it deploys inside it: with `app`,
`node_modules/a/x.js` deploys at `app/node_modules/a/x.js`.

The tracer is ESM only: no CommonJS, no `main` field, no Node builtins. It began
as a cut-down [@vercel/nft](https://github.com/vercel/nft); the resolver and the
static evaluation of `import()` arguments still come from there.

---
_Source: https://npm.io/package/@mikrojs/analyze-imports · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
