# @equinor/fusion-imports

> Package import files and configurations

Latest version **2.0.5** (published 2026-09-29) · ISC license · 0 weekly downloads

## Install

```sh
npm install @equinor/fusion-imports
pnpm add @equinor/fusion-imports
yarn add @equinor/fusion-imports
bun add @equinor/fusion-imports
```

## Health

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

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

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.0.5 |
| Published | 2026-09-29 |
| First published | 2025-03-27 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 2 |
| Unpacked size | 216.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | _odin_, nogglings, eikeland |
| Keywords | esbuild, typescript, transpiling, node, runtime |

## Links

- npm: https://www.npmjs.com/package/@equinor/fusion-imports
- Repository: https://github.com/equinor/fusion-framework
- Issues: https://github.com/equinor/fusion-framework/issues
- npm.io page: https://npm.io/package/@equinor/fusion-imports

## Dependencies (2)

- [esbuild](https://npm.io/package/esbuild.md) ^0.28.1
- [read-package-up](https://npm.io/package/read-package-up.md) ^12.0.0

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 2.0.5 (latest) — 2026-09-29
- 2.0.3-next.1 (next) — 2026-08-26
- 1.1.11-msal-v5.0 (msal-v5) — 2026-01-26
- 1.1.7-cli-search-index.0 (cli-search-index) — 2025-11-14
- 1.1.1-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9 (apploader) — 2025-05-30
- 2.0.4 — 2026-08-31
- 2.0.3 — 2026-08-31
- 2.0.3-next.0 — 2026-08-16
- 2.0.2 — 2026-07-30
- 2.0.1 — 2026-07-29
- 2.0.0 — 2026-03-18
- 1.1.12-next.0 — 2026-03-11
- 1.1.11 — 2026-03-09
- 1.1.10 — 2026-01-26
- 1.1.9 — 2026-01-20
- … 18 more at https://npm.io/package/@equinor/fusion-imports/versions

## README

# @equinor/fusion-imports

Utilities for importing and transpiling TypeScript, JavaScript, and JSON configuration files at **Node.js runtime** using [esbuild](https://esbuild.github.io/).

> [!IMPORTANT]
> This package works with **file paths**, not URLs. It is designed for loading configuration scripts at runtime in Node.js CLI tools and build pipelines.

## Installation

```bash
pnpm add @equinor/fusion-imports
```

## When to use

| Scenario | Function |
|---|---|
| Load a config by basename, auto-resolving `.ts` → `.js` → `.json` | `importConfig` |
| Bundle & import a single TypeScript/JS module at runtime | `importScript` |
| Read and parse a JSON file from disk | `importJSON` |
| Find the first accessible config file for a basename | `resolveConfigFile` |

## Quick start

```typescript
import { importConfig } from '@equinor/fusion-imports';

interface AppSettings {
  name: string;
  port: number;
}

// Resolves app.config.ts → app.config.js → app.config.json
const { config, path } = await importConfig<AppSettings>('app.config');
console.log(`Loaded ${path}:`, config);
```

## API

### `importConfig<C>(basename, options?)`

Resolves a configuration file by basename, probing extensions in order (`.ts`, `.mjs`, `.js`, `.json`). JSON files are parsed directly; script files are bundled with esbuild and dynamically imported.

```typescript
import { importConfig } from '@equinor/fusion-imports';

interface MyConfig {
  name: string;
  bar: { foobar: number };
}

interface ScriptModule {
  generateConfig: (options: { env: string }) => MyConfig;
}

const { config } = await importConfig<MyConfig, ScriptModule>('my-config', {
  script: {
    resolve: (module) => module.generateConfig({ env: 'production' }),
  },
});
```

By default the module's `default` export is used as the config value. Provide `script.resolve` to extract a different export or call a factory function.

#### Options

| Option | Type | Description |
|---|---|---|
| `baseDir` | `string` | Base directory for file resolution (default: `process.cwd()`) |
| `extensions` | `string[]` | Extensions to probe (default: `['.ts', '.mjs', '.js', '.json']`) |
| `script.resolve` | `(module) => C` | Extracts the config value from the imported module |
| `script.esBuildOptions` | `ImportScriptOptions` | Esbuild overrides forwarded to `importScript` |

### `importScript<M>(entryPoint, options?)`

Bundles a TypeScript or JavaScript file with esbuild (ESM, external packages) and dynamically imports the output. Two built-in esbuild plugins are included automatically:

- **`importMetaResolvePlugin`** — resolves `import.meta.resolve()` calls for relative paths at build time.
- **`rawMarkdownPlugin`** — supports `?raw` imports for `.md` / `.mdx` files.

```typescript
import { importScript } from '@equinor/fusion-imports';

interface Greeting { greet(name: string): string }
const mod = await importScript<Greeting>('./greet.ts');
console.log(mod.greet('World'));
```

#### Esbuild customisation

`ImportScriptOptions` inherits all `esbuild.BuildOptions` except `entryPoints`, `bundle`, and `format`. You can pass custom plugins, define aliases, or change the output directory:

```typescript
import { importScript } from '@equinor/fusion-imports';
import alias from 'esbuild-plugin-alias';

const mod = await importScript('./entry.ts', {
  plugins: [alias({ '@app': './src' })],
  outfile: '/tmp/bundle.js',
});
```

### `importJSON<T>(filePath, encoding?)`

Reads a JSON file from disk and returns the parsed content. Throws with the original error as `cause` if the file is unreadable or contains invalid JSON.

```typescript
import { importJSON } from '@equinor/fusion-imports';

interface Manifest { name: string; version: string }
const manifest = await importJSON<Manifest>('./package.json');
```

### `resolveConfigFile(baseName, options?)`

Returns the absolute path of the first accessible configuration file matching the given basename and extension list. Useful when you need the path without importing the file.

```typescript
import { resolveConfigFile } from '@equinor/fusion-imports';

const configPath = await resolveConfigFile('app.config', {
  baseDir: '/project',
  extensions: ['.ts', '.json'],
});
```

### Plugins

#### `rawMarkdownPlugin(options?)`

Esbuild plugin that intercepts `?raw` imports for markdown files and returns
their content as a default-exported string. Included automatically by `importScript`.

```typescript
// In a file bundled by importScript:
import readme from '../../README.md?raw';
console.log(readme); // raw markdown string
```

#### `createImportMetaResolvePlugin()`

Esbuild plugin that replaces `import.meta.resolve('./relative')` calls with
resolved `file://` URLs at build time. Included automatically by `importScript`.

### Error handling

The package provides two error classes for filesystem failures:

| Error | Thrown when |
|---|---|
| `FileNotFoundError` | File does not exist (`ENOENT`) |
| `FileNotAccessibleError` | File exists but cannot be read (`EACCES`, `EISDIR`) |

Both extend `Error` and attach the original Node.js error as `cause`:

```typescript
import { importConfig, FileNotFoundError } from '@equinor/fusion-imports';

try {
  await importConfig('missing');
} catch (error) {
  if (error instanceof FileNotFoundError) {
    console.error('Config not found:', error.message);
  }
}
```

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