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

rust-imports

v0.1.4

Published

Import adjacent Rust files as content-addressed napi-rs modules in Bun.

Readme

rust-imports

npm version

Import a Rust file beside TypeScript and use its top-level napi-rs exports as a normal Bun module:

import { add } from './math.rs';

console.log(add(5, 7));

Install the published package from npm:

bun add rust-imports

To test an unreleased revision, install the Git repository directly. Git installs are pinned to a commit in bun.lock; run bun update rust-imports when you intentionally want to adopt a newer repository revision.

bun add https://github.com/MichaelRogatinsky/rust-imports.git

Requirements

  • Bun 1.4 or newer.
  • Rust and Cargo 1.83 or newer for a missing or stale native artifact.
  • A working C linker for the host platform.
  • Registry access on the first build so Cargo can download the pinned napi-rs v2 dependency set.

The package currently builds native addons for the host operating system and architecture. Rust source is trusted project code: compiling and inspecting an addon can execute its native module initialization.

Write an adjacent Rust module

math.rs needs no local Cargo manifest. The generated isolated crate supplies napi, napi-derive, and napi-build:

use napi_derive::napi;

#[napi]
pub fn add(left: i32, right: i32) -> i32 {
    left + right
}

Import it from a neighboring TS or JS file:

import { add } from './math.rs';

Register the Bun runtime adapter

The zero-configuration preload uses the current working directory as its source boundary. Add it to bunfig.toml for development and tests:

preload = ["rust-imports/register"]

[test]
preload = ["rust-imports/register"]

The register entrypoint uses a process-global guard, so loading it more than once does not install duplicate plugins.

For a narrower boundary or custom compiler options, create your own preload:

import { rustImportsPlugin } from 'rust-imports/runtime';

Bun.plugin(
  rustImportsPlugin({
    rootDir: import.meta.dir,
    release: false
  })
);

At runtime, the plugin validates the import path, reuses a verified artifact when possible, and invokes Cargo when the artifact is missing or stale. If Cargo is not available, it fails with a build instruction instead of silently loading an unverified binary.

TypeScript declarations

Enable arbitrary-extension declarations in tsconfig.json:

{
  "compilerOptions": {
    "allowArbitraryExtensions": true,
    "types": ["bun"]
  }
}

Compiling math.rs writes math.d.rs.ts beside it. TypeScript recognizes that name as the declaration for math.rs. Generated declarations expose inspected exports as any; a handwritten declaration without the generated marker is preserved and can provide richer types.

Run the preparation step before a clean typecheck so the declaration exists. Choose one project policy deliberately:

  • commit generated or handwritten *.d.rs.ts files; or
  • regenerate them before every typecheck and keep them ignored.

Install @types/bun in TypeScript consumers if it is not already part of the Bun project setup.

Prepare a dependency graph

The programmatic build adapter discovers reachable local TS/JS modules, compiles their adjacent Rust imports, and does not mutate source by default:

import { prepareRustImports } from 'rust-imports/build';

const result = await prepareRustImports({
  entrypoints: ['server.ts'],
  rootDir: process.cwd(),
  release: true,
  rewrite: 'none'
});

console.log(result.artifacts);

The installed CLI exposes the same workflow:

{
  "scripts": {
    "build:native": "rust-imports --entrypoint ./server.ts",
    "build:vercel": "rust-imports --entrypoint ./server.ts --release --rewrite=in-place"
  }
}

Useful CLI options:

--entrypoint <file>       Repeatable entrypoint relative to --root
--root <directory>        Source boundary; defaults to the current directory
--cache-dir <directory>   Defaults to <root>/.rust-imports
--release | --debug       Select the Cargo profile
--force                   Ignore a valid cached artifact
--rewrite none|in-place   Compile only, or rewrite imports to generated proxies

in-place rewriting is for disposable build checkouts. Outside Vercel, the CLI requires the explicit --allow-source-mutation acknowledgement. Rewriting is transactional across the discovered import graph, changes only correlated import specifiers, and never deletes .rs sources.

Cache and generated artifacts

The default layout is:

.rust-imports/
  artifacts/   content-addressed .mjs proxies and host .node addons
  crates/      generated isolated Cargo crates
  state/       verified dependency fingerprints
  target/      shared Cargo build output

Add .rust-imports/ to .gitignore. It is a rebuildable cache and can be removed when no build or Bun process is using it. Do not treat *.d.rs.ts the same way unless the project regenerates declarations before typechecking. The package never deletes Rust source files.

Vercel

Run the release build and in-place rewrite from Vercel's custom build command so function tracing sees ordinary .mjs proxies and adjacent .node files:

{
  "bunVersion": "1.4.x",
  "buildCommand": "bun run build:vercel",
  "functions": {
    "server.ts": {
      "includeFiles": ".rust-imports/artifacts/**/*",
      "excludeFiles": "{.rust-imports/crates/**,.rust-imports/target/**,**/*.rs}"
    }
  }
}

The build:vercel script shown above rewrites only Vercel's disposable checkout. The emitted proxy and native addon stay adjacent inside artifacts/, so Vercel's file tracing preserves their relative load path. Ensure Rust 1.83+, Cargo, and a linker are on the build image's PATH; native compilation is not a runtime fallback on a packaged function.

For Vercel Services, place the same buildCommand and functions fields on the service whose root contains the entrypoint.

Public entrypoints

  • rust-imports — curated runtime, build, compiler, and public types.
  • rust-imports/register — guarded zero-config Bun preload.
  • rust-imports/runtime — runtime plugin and runtime options.
  • rust-imports/build — dependency-graph preparation.
  • rust-imports/compiler — low-level single-module compilation.
  • rust-imports/types — shared public TypeScript types.

Version 0.1 limitations

  • Builds only for the host platform and architecture; there is no cross compile.
  • Generated declarations use any; rich napi-rs type generation is not included.
  • Generated Cargo manifests do not accept custom dependency configuration.
  • Build graph discovery follows local relative/absolute imports, not bare aliases.
  • A plugin-unaware bundler must consume the explicit rewritten graph.

Development

Install the locked development toolchain and run the complete local checks:

bun install --frozen-lockfile
bun test
bun run build
bun run smoke:pack

The generated dist/ directory is committed because direct Git dependencies do not reliably run package lifecycle builds. Regenerate it with bun run build whenever the TypeScript source changes; CI rejects stale generated output.

The compiler safety tests build a tiny raw Node-API fixture with rustc; they do not search a surrounding workspace for an installed native dependency or contact the Cargo registry. CI runs these checks with Bun 1.4.0 and Rust 1.83.0.

Releasing

Releases are driven by version tags. From a clean, up-to-date main branch, choose the appropriate semantic-version increment and push the commit and tag:

npm version patch
git push origin main --follow-tags

Use minor or major instead of patch when appropriate. The release workflow checks that the tag matches package.json, runs the complete test and package validation suite, publishes to npm through trusted publishing, and creates the matching GitHub Release.