{"id":13593322,"url":"https://github.com/tonysm/importmap-laravel","last_synced_at":"2026-02-28T23:07:02.378Z","repository":{"id":39616630,"uuid":"449504570","full_name":"tonysm/importmap-laravel","owner":"tonysm","description":"Use ESM with import maps to manage modern JavaScript in Laravel without transpiling or bundling.","archived":false,"fork":false,"pushed_at":"2025-06-23T17:43:58.000Z","size":399,"stargazers_count":143,"open_issues_count":1,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-23T18:42:45.162Z","etag":null,"topics":["hacktoberfest","importmap","laravel"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tonysm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"tonysm"}},"created_at":"2022-01-19T01:22:53.000Z","updated_at":"2025-06-23T17:43:59.000Z","dependencies_parsed_at":"2023-11-12T19:23:38.549Z","dependency_job_id":"f22537ff-a7f6-4c3f-826c-3e218be581e3","html_url":"https://github.com/tonysm/importmap-laravel","commit_stats":{"total_commits":157,"total_committers":4,"mean_commits":39.25,"dds":"0.19108280254777066","last_synced_commit":"b9f829743e19721d9d081f038521296dd9f1b697"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":"spatie/package-skeleton-laravel","purl":"pkg:github/tonysm/importmap-laravel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonysm%2Fimportmap-laravel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonysm%2Fimportmap-laravel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonysm%2Fimportmap-laravel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonysm%2Fimportmap-laravel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tonysm","download_url":"https://codeload.github.com/tonysm/importmap-laravel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonysm%2Fimportmap-laravel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29954583,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T22:53:01.873Z","status":"ssl_error","status_checked_at":"2026-02-28T22:52:50.699Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","importmap","laravel"],"created_at":"2024-08-01T16:01:19.166Z","updated_at":"2026-02-28T23:07:02.366Z","avatar_url":"https://github.com/tonysm.png","language":"PHP","funding_links":["https://github.com/sponsors/tonysm"],"categories":["PHP"],"sub_categories":[],"readme":"\u003cp align=\"center\" style=\"margin-top: 2rem; margin-bottom: 2rem;\"\u003e\u003cimg src=\"/art/importmap-laravel-logo.svg\" alt=\"Logo Importmap Laravel\" /\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://packagist.org/packages/tonysm/importmap-laravel\"\u003e\u003cimg src=\"https://img.shields.io/packagist/dt/tonysm/importmap-laravel.svg?style=flat-square\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/tonysm/importmap-laravel\"\u003e\u003cimg src=\"https://img.shields.io/packagist/v/tonysm/importmap-laravel\" alt=\"Latest Stable Version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/tonysm/importmap-laravel\"\u003e\u003cimg src=\"https://img.shields.io/packagist/l/tonysm/importmap-laravel\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Introduction\n\nUse ESM with importmap to manage modern JavaScript in Laravel without transpiling or bundling.\n\n### Inspiration\n\nThis package was inspired by the [Importmap Rails](https://github.com/rails/importmap-rails) gem. Some pieces of this README were copied straight from there and adapted to the Laravel version.\n\n### How does it work?\n\n[Import maps](https://github.com/WICG/import-maps) lets you import JavaScript modules directly from the browser using logical names that map to versioned/digested files. So you can [build modern JavaScript applications using JavaScript libraries made for ES modules (ESM) without the need for transpiling or bundling](https://world.hey.com/dhh/modern-web-apps-without-javascript-bundling-or-transpiling-a20f2755). This frees you from needing Webpack, Yarn, npm, or any other part of the JavaScript toolchain.\n\nWith this approach, you'll ship many small JavaScript files instead of one big JavaScript file. Thanks to HTTP/2 that no longer carries a material performance penalty during the initial transport, and offers substantial benefits over the long run due to better caching dynamics. Whereas before any change to any JavaScript file included in your big bundle would invalidate the cache for the whole bundle, now only the cache for that single file is invalidated.\n\n[Import maps are supported natively in all major, modern browsers](https://caniuse.com/?search=importmap). If you need to work with legacy browsers without native support, you may want to explore using [the shim available](https://github.com/guybedford/es-module-shims).\n\n## Installation\n\nYou can install the package via Composer:\n\n```bash\ncomposer require tonysm/importmap-laravel\n```\n\nThe package has an `install` command that you may run to replace the default Laravel scaffold with one to use importmap:\n\n```bash\nphp artisan importmap:install\n```\n\nNext, we need to add the following component to our view or layout file:\n\n```blade\n\u003cx-importmap::tags /\u003e\n```\n\nAdd that between your `\u003chead\u003e` tags. The `entrypoint` should be the \"main\" file, commonly the `resources/js/app.js` file, which will be mapped to the `app` module (use the module name, not the file).\n\nBy default, the `x-importmap::tags` component assumes your entrypoint module is `app`, which matches the existing `resources/js/app.js` file from Laravel's default scaffolding. You may want to customize the entrypoint, which you can do with the `entrypoint` prop:\n\n```blade\n\u003cx-importmap::tags entrypoint=\"admin\" /\u003e\n```\n\nThe package will automatically map the `resources/js` folder to your `public/js` folder using Laravel's symlink feature. All you have to do after installing the package is run:\n\n```bash\nphp artisan storage:link\n```\n\nIf you're using Laravel Sail, make sure you prefix that command with `sail` as the symlink needs to be created inside the container.\n\nThe symlink is only registered in local environments. For production, it's recommended to run the `importmap:optimize` command instead:\n\n```php\nphp artisan importmap:optimize\n```\n\nThis should scan all your pinned files/folders (no URLs) and publish them to `public/dist/js`, adding a digest based on the file's content to the file name - so something like `public/dist/js/app-123123.js`, and then generate a `.importmap-manifest.json` file in the `public/` folder. This file will get precedence over your pins. If you run that by accident in development, manually delete that file or run `php artisan importmap:clear`, which should delete it for you. You may also want to add the `/public/dist` path and the `*importmap-manifest.json` file to your `.gitignore` file.\n\n## Usage\n\nIn a nutshell, importmap works by giving the browser a map of where to look for your JavaScript import statements. For instance, you could _pin_ a dependency in the `routes/importmap.php` file for Alpinejs like so:\n\n```php\n\u003c?php\n\nuse Tonysm\\ImportmapLaravel\\Facades\\Importmap;\n\n// Other pins...\nImportmap::pin(\"alpinejs\", to: \"/js/vendor/alpinejs.js\"); //@3.8.1\n```\n\nThen, in your JavaScript files, you can safely do:\n\n```js\nimport Alpine from 'alpinejs';\n```\n\n### Pinning Local Files\n\nLocal pins should be added to the `routes/importmap.php` file manually, like so:\n\n```php\nImportmap::pin(\"app\", to: \"/js/app.js\");\n```\n\nThis means that the `app` module will point to `/js/app.js` in the browser. This is the URI the browser will use to fetch the file, not the path to the file itself. Pins to local files assume a relative path of `resources/js/` to find them.\n\n### Pinning Local Directories\n\nDeclaring all your local files can be tedious, so you may want to map an entire folder like so:\n\n```php\nImportmap::pinAllFrom(\"resources/js/\", to: \"js/\");\n```\n\nWhen we're generating the importmap JSON, we'll scan that directory looking for any `.js` or `.jsm` files inside of it and generate the correct importmap for them based on their relative location. There are a couple of interesting rules, though, something like:\n\n| Path | Module | URI |\n|---|---|---|\n| `resources/js/app.js` | `app` | `/js/app.js` |\n| `resources/js/controllers/hello_controller.js` | `controllers/hello_controller` | `/js/controllers/hello_controller.js` |\n| `resources/js/libs/index.js` | `libs` | `/js/libs/index.js` |\n\nIf there's an `index.js` file in a folder, we won't get `index` in the module name, so we can import it like\n\n```js\nimport libs from 'libs';\n```\n\nInstead of\n\n```js\nimport libs from 'libs/index';\n```\n\n### Pinning External Dependencies\n\nIf you depend on any external library you can use the `importmap:pin` command to pin it, like so:\n\n```bash\nphp artisan importmap:pin alpinejs\n```\n\nIt will download the `alpinejs` lib, then it will add the following line to your `routes/importmap.php` file:\n\n```php\nImportmap::pin(\"alpinejs\", to: \"/js/vendor/alpinejs.js\"); // @3.8.1\n```\n\nThe `pin` command makes use of the jspm.io API to resolve the dependencies (and the dependencies of our dependencies), looking for ESM modules that we can pin, and resolving it to a CDN URL and downloading as a dependency. We can control the CDN we want to use by specifying the `--from` flag like so:\n\n```bash\nphp artisan importmap:pin alpinejs --from=unpkg\n```\n\nThis will download the lib from unpkg instead of the default JSPM CDN.\n\nIt's important to note that the `pin` command will always resolve the dependencies (and the dependencies of our dependencies) and download all the files to your `resources/js/vendor` folder, which you should add to your version control and vendor it yourself. The pin will look like this:\n\n```php\nImportmap::pin(\"alpinejs\", to: \"/js/vendor/alpinejs.js\"); // @3.8.1\n```\n\nThe version is added as a comment to your pin so you know which version was imported. Don't remove that as it's gonna be useful later on when you need to upgrade your dependencies.\n\n### Preloading Modules\n\nTo avoid the waterfall effect where the browser has to load one file after another before it can get to the deepest nested import, we use [modulepreload links](https://developers.google.com/web/updates/2017/12/modulepreload) by default. If you don't want to preload a dependency, because you want to load it on-demand for efficiency, append `preload: false` to the pin.\n\n```php\nImportmap::pinAllFrom(\"resources/js/\", to: \"js/\", preload: true);\nImportmap::pin(\"alpinejs\", to: \"https://unpkg.com/alpinejs@3.8.1/dist/module.esm.js\", preload: true); // @3.8.1\n```\n\nWhich will add the correct `links` tags to your head tag in the HTML document, like so:\n\n```html\n\u003clink rel=\"modulepreload\" href=\"https://unpkg.com/alpinejs@3.8.1/dist/module.esm.js\"\u003e\n```\n\n## Dependency Maintenance Commands\n\nMaintaining a healthy dependency list can be tricky. Here are a couple of commands to help you with this task.\n\n### Outdated Dependencies\n\nTo keep your dependencies up-to-date, make sure you run the `importmap:outdated` command from time to time:\n\n```bash\nphp artisan importmap:outdated\n```\n\nThis command will scan your `routes/importmap.php` file, find your current versions, and then use the NPM registry API to look for the latest version of the packages you're using. It also handles locally served vendor libs that you added using the `--download` flag from the `importmap:pin` command.\n\n### Auditing Dependencies\n\nIf you want a security audit on your dependencies to see if you're using a version that's been breached, run the `importmap:audit` command from time to time. Better yet, add that command to your CI build:\n\n```bash\nphp artisan importmap:audit\n```\n\nThis will also scan your `routes/importmap.php` file, find your current versions, and then use the NPM registry API to look for vulnerabilities in your packages. It also handles locally served vendor libs that you added using the `--download` flag from the `importmap:pin` command.\n\n## Known Problems\n\n### On React's JSX and Vue's SFC\n\nIt's possible to use both React and Vue with importmaps but, unfortunately, you would have to use those without the power of JSX or SFC. That's because those file types need a compilation/transpilation step where they are converted to something the browser can understand. There are alternative ways to use both these libraries, but I should say that these are not \"common\" ways in their communities. You may use [React with HTM](https://github.com/developit/htm). And you can use Vue just fine without SFC, the only difference is that your templates would be in Blade files, not a SFC file.\n\n### Process ENV Configs\n\nYou may be used to having a couple `process.env.MIX_*` lines in your JS files here and there. The way this works is Webpack would replace at build time of your calls to `process.env` with the values it had during the build. Since we don't have a \"build time\" anymore, this won't work. Instead, you should add `\u003cmeta\u003e` tags to your layout file with anything that you want to make available to your JavaScript files and use `document.head.querySelector('meta[name=my-config]').content` instead of relying on the `process.env`.\n\nConsider using something like [`current.js`](https://www.npmjs.com/package/current.js) to easily consume your `\u003cmeta\u003e` configs using a globally available `Current` object.\n\n## Testing\n\n```bash\ncomposer test\n```\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.\n\n## Security Vulnerabilities\n\nPlease review [our security policy](../../security/policy) on how to report security vulnerabilities.\n\n## Credits\n\n- [Tony Messias](https://github.com/tonysm)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonysm%2Fimportmap-laravel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftonysm%2Fimportmap-laravel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonysm%2Fimportmap-laravel/lists"}