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

@emdzej/bimmerz-bundler

v0.6.6

Published

Curate a BMW software install (INPA / EDIABAS / NCS) into a small zip web tools (inpax-web, future ediabasx-web, future ncsx) can import into OPFS. Uses gitignore-style exclude patterns.

Downloads

1,018

Readme

@emdzej/bimmerz-bundler

CLI tool that curates a BMW software install (INPA / EDIABAS / NCS) into a small zip web tools — inpax-web, and future ediabasx-web / ncsx — can import into OPFS.

Why

A real BMW install can be multiple GB — most of it executables, DLLs, help files, label-printer assets, and other content the browser tools never read. Uploading the whole thing wastes user time and OPFS quota. This tool walks the install with gitignore-style filtering so users can produce a zip with just the content their target tool needs.

Also sidesteps Chrome's .ini File System Access blocklist on Windows — anything that goes into OPFS is readable, regardless of extension.

The CLI is product-agnostic: the same binary serves inpax (INPA scripts + SGBDs), the future ediabasx-web (just EDIABAS/Bin + EDIABAS/Ecu), and a future ncsx (NCSEXPER + EDIABAS/Ecu). The ignore patterns are how you scope to the product you care about.

Install / build

pnpm --filter @emdzej/bimmerz-bundler build

After build the binary is at dist/cli.js and is registered via bin so pnpm exec bimmerz-bundle works inside the workspace.

Quick start

# 1. Get a starter .bimmerzignore next to your BMW install.
pnpm exec bimmerz-bundle init ~/Downloads/inpa/.bimmerzignore

# 2. Open the file, add product-specific overrides if you want.
${EDITOR:-vi} ~/Downloads/inpa/.bimmerzignore

# 3. Build the bundle.
pnpm exec bimmerz-bundle ~/Downloads/inpa --output ~/inpa-bundle.zip

The bundle is the file you upload via the web tool's "Import bundled install" UI (coming soon).

Reusing the bundle without a web tool

A bundle is just a standard zip with paths preserved relative to the install root (EC-APPS/INPA/SGDAT/MS43.IPO, EDIABAS/Ecu/MS43.prg, …). Nothing forces you to feed it to a browser — you can also extract it back to disk and use the result as a smaller, curated copy of the install for any tool that takes a folder path (Tool32, NCS Expert, the inpax-web "Pick folder" picker, etc.). Round-trip example:

bimmerz-bundle ~/Downloads/inpa --output ~/inpa-trimmed.zip
unzip ~/inpa-trimmed.zip -d ~/inpa-trimmed/
# now point INPA / Tool32 / inpax-web at ~/inpa-trimmed

Subcommands

bundle <input-dir> (default)

Walks the install, applies the ignore filter, writes a zip.

| Flag | Meaning | | --- | --- | | -o, --output <file> | Where the zip lands. Defaults to ./bimmerz-bundle.zip. | | -i, --ignore <file> | Path to a .bimmerzignore. Defaults to <input-dir>/.bimmerzignore if it exists. | | --no-default-ignore | Skip the built-in install-junk patterns (only your file applies). | | --dry-run | Walk + match without writing the zip. Prints what would be kept. | | --verbose | Log every kept and skipped file. Slow on full installs; pipe to a file. |

init [path]

Writes the canonical default exclude patterns to disk as a starter template. path defaults to ./.bimmerzignore.

| Flag | Meaning | | --- | --- | | -f, --force | Overwrite an existing file (otherwise refuses). |

Pattern language

Standard gitignore semantics, parsed by the ignore package. Highlights:

  • *.exe — match any file whose name ends in .exe.
  • Log/ — trailing slash = directory only.
  • **/Pic/ — leading two-star glob = any depth. Matches Pic/ anywhere in the tree.
  • !pattern — negation. Bring something back that an earlier pattern excluded.
  • Order matters with negations; later wins.

Matching is case-insensitive so *.exe catches INPA.EXE, Inpa.Exe, and inpa.exe alike. This is important — Windows installs use mixed casing, Linux mirrors may be all lowercase, and macOS-imported copies sometimes shuffle case in unicode- normalisation-sensitive paths.

Gotcha: re-including from an excluded directory

This does not work:

EDIABAS/
!EDIABAS/Ecu

It looks intuitive — "exclude EDIABAS, but bring back Ecu" — but gitignore explicitly disallows re-including a path whose parent directory is excluded. From git's own docs:

It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn't list excluded directories for performance reasons, so any patterns on contained files have no effect.

The bundler's walker enforces the same rule — once a directory is excluded it never descends, so the negation never gets a chance to fire on anything inside.

Correct form — exclude the children of the parent instead of the parent itself, so the walker still descends and the negation can match:

EDIABAS/*
!EDIABAS/Ecu/

The EDIABAS/* glob (no trailing slash) excludes everything immediately under EDIABAS/ without marking EDIABAS/ itself as excluded. The walker still enters the directory, sees Ecu/, and the !EDIABAS/Ecu/ negation re-includes it.

If you want to drill deeper — say, exclude all of EDIABAS/ except one specific file under EDIABAS/Ecu/ — you have to repeat the dance at every level:

EDIABAS/*
!EDIABAS/Ecu/
EDIABAS/Ecu/*
!EDIABAS/Ecu/MS43.prg

Annoying, but consistent with every gitignore-style matcher in existence.

Defaults shipped

See src/default-ignore.ts for the authoritative list. Summary of what's excluded by default — these apply across INPA / EDIABAS / NCS because they're install-wide junk (executables, OS files, runtime directories):

  • Executables / DLLs / scripts (*.exe, *.dll, *.bat, …)
  • Help files (*.chm, *.hlp, *.pdf)
  • Backups / temp / OS junk (*.bak, .DS_Store, Thumbs.db)
  • Runtime / install-time dirs (Log/, NET/, Pic/, Server/, Utils/, Setup/)
  • EDIABAS/Bin/** except *.INI / *.INIX (cable cfg files only)

Notable kept: *.ipo, *.prg, *.grp, *.ini, *.inix, *.eng, *.ger, *.cps, *.ipx — i.e. all the things scripts or NCS tooling actually read.

Product-specific tightening

Use a project .bimmerzignore to narrow what gets bundled:

# inpax-web setup (no NCSEXPER, no Doku/Source/Hardware/Api):
NCSEXPER/
EDIABAS/Doku/
EDIABAS/Source/
EDIABAS/Hardware/
EDIABAS/Api/
EDIABAS/HELP/

# Only specific chassis SGBDs:
EDIABAS/Ecu/**.{prg,grp,PRG,GRP}
!EDIABAS/Ecu/MS43*
!EDIABAS/Ecu/EWS*
!EDIABAS/Ecu/AGS*

Dry-run example

pnpm exec bimmerz-bundle ~/Downloads/inpa --dry-run

Sample output:

Done.
  kept    : 12469 files (1.72 GB)
  skipped : 287 files
  output  : (dry-run, no zip written)
  elapsed : 0.52s

If kept is 0 you almost certainly have a too-broad negation in your .bimmerzignore. A bundle warning fires above 500 MB — tighten the ignore file or pick a narrower input subtree.

Symlinks / case-collisions

  • Symlinks: skipped with a [symlink] reason in --verbose. BMW installs don't use them; following risks loops or escaping the walk root.
  • Case-colliding entries (e.g. both MS43.IPO and ms43.ipo in the same dir after a cross-platform sync): both go into the zip; the browser-side reader on the OPFS side is already case- insensitive everywhere, so first-seen wins.

Nested ignore files (not yet supported)

Currently the tool reads one ignore file (from --ignore, or auto-picked from <input>/.bimmerzignore). Per-directory nested .bimmerzignore files like git's nested .gitignore aren't supported yet — the install tree is flat enough that one root file covers the typical cases. If you have a use case that needs nested scoping, file an issue.

What this tool does NOT do

  • Doesn't connect to BMW, doesn't read your data — purely a local file packaging utility.
  • Doesn't validate that the install is "complete" — that's the target tool's job (inpax-web/discoverInpaInstall, etc.).
  • Doesn't ship sample BMW content — the bundle is your own data.