Getting started

# Overview

A drop-in replacement for importmap-rails with vendoring that keeps its promises.

## What it is

[importmap-rails](https://github.com/rails/importmap-rails) lets a Rails app import JavaScript modules by logical name, straight from the browser, with no bundler. importmap-plus is that gem, forked, with the vendoring story finished: `bin/importmap` downloads what you ask for, remembers where it came from, minifies it when you say so, and leaves alone what you have locked.

The `Importmap::` constants, the `pin` DSL, `config/importmap.rb`, the view helpers and the generated import map are unchanged. An app switches by replacing one line in its Gemfile. The importmap-rails release this tracks is in `Importmap::UPSTREAM_VERSION`.

> **One or the other:** Install importmap-plus or importmap-rails, never both — they define the same `Importmap::` constants and the same Rails engine.

## What it adds

Everything below is bin/importmap; the runtime is untouched.

| Feature | What it does | Docs |
| --- | --- | --- |
| `pin --minify` | Runs a download through bun, esbuild or terser before it lands in vendor/javascript; later updates keep minifying. | [Minifying](https://importmap-plus.zoolutions.llc/docs/minifying) |
| `--from esm.run` | Vendors jsDelivr's one-file bundle, rewrites its imports to bare specifiers, and pins the dependencies it needs. | [esm.run bundles](https://importmap-plus.zoolutions.llc/docs/esm-run) |
| `pin --lock` | Holds a package at a version. update, pristine and pin leave it there until you unlock it or pass --force. | [Locking versions](https://importmap-plus.zoolutions.llc/docs/locking) |
| `update [PACKAGES] --all --force` | Update by name, or everything explicitly; --force moves locked packages and re-locks them. | [Updating & auditing](https://importmap-plus.zoolutions.llc/docs/updating) |
| Provenance | The pin comment records the CDN, minification and lock, so nothing silently drifts back to jspm. | [Provenance](https://importmap-plus.zoolutions.llc/docs/provenance) |
| Remote pins stay remote | A pin with a CDN URL is re-resolved from that CDN; preload: and boolean integrity: survive every rewrite. | [Pinning packages](https://importmap-plus.zoolutions.llc/docs/pinning) |
| Requests retry | A reset connection, a timeout or a 429/5xx is tried three times with a growing pause before the command gives up. | [Configuration](https://importmap-plus.zoolutions.llc/docs/configuration) |

## What stays the same

The parts of importmap-rails you build on are exactly as upstream ships them:

- `pin`, `pin_all_from` and `enable_integrity!` in `config/importmap.rb`,
- `javascript_importmap_tags` and `javascript_import_module_tag` in your layouts,
- `Rails.application.importmap`, `Importmap::Map`, the cache sweeper and the reloader,
- `Rails.application.config.importmap.*`,
- `bin/importmap json`, `audit`, `outdated`, `packages`, `unpin` and `pristine`.

Those pages of these docs are importmap-rails' own documentation, kept in step with the upstream release this gem tracks.

## Where next

- New app, or an app on importmap-rails today: [Installation](https://importmap-plus.zoolutions.llc/docs/installation).
- Coming from importmap-rails and wondering what changes: [Upgrading from importmap-rails](https://importmap-plus.zoolutions.llc/docs/upgrading).
- Every command and flag on one page: [CLI reference](https://importmap-plus.zoolutions.llc/docs/cli).