Skip to content

Composable asset pipeline with bun and TypeScript support - #1

Closed
jimsynz wants to merge 1 commit into
mainfrom
bun-ts
Closed

jimsynz wants to merge 1 commit into
mainfrom
bun-ts

Conversation

@jimsynz

@jimsynz jimsynz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Refactors phx.install.assets from a monolithic task into a composable orchestrator with pluggable bundler and CSS runner subtasks
  • Adds Bun as an alternative bundler to esbuild, using the bun hex package — npm workspace deps instead of vendored JS, bun profiles for JS and CSS
  • Adds --lang=ts option for both bundlers, generating a well-factored TypeScript entry point
  • Tailwind CSS runner is dynamically dispatched via task naming convention (phx.install.assets.tailwind.#{bundler}), so adding a new bundler requires no changes to existing files

New flags on phx.install.assets

Flag Values Default
--bundler esbuild, bun esbuild
--lang js, ts js
--tailwind boolean true
--js-test boolean false

Task composition

phx.install.assets (orchestrator)
├── phx.install.assets.static
├── phx.install.assets.live_reload
├── phx.install.assets.esbuild OR phx.install.assets.bun
└── phx.install.assets.tailwind
    ├── phx.install.assets.tailwind.esbuild
    └── phx.install.assets.tailwind.bun

Test plan

  • All 164 existing tests pass (0 failures)
  • New tests cover: esbuild default, --no-tailwind, --lang ts, --bundler bun, --bundler bun --lang ts, --js-test opt-in and default-off
  • Manual testing with mix phx.install.assets --bundler bun --lang ts in a fresh project
  • Verify bun watcher and CSS profile work in dev

Refactor `phx.install.assets` from a monolithic task into a composable
orchestrator with pluggable bundler and CSS runner subtasks.

New flags on `phx.install.assets`:
- `--bundler=esbuild|bun` (default: esbuild)
- `--lang=js|ts` (default: js)
- `--tailwind/--no-tailwind` (default: true)
- `--js-test/--no-js-test` (default: false, bun only)

New subtasks:
- `phx.install.assets.static` — robots.txt + favicon
- `phx.install.assets.live_reload` — live_reload config in dev.exs
- `phx.install.assets.esbuild` — esbuild hex dep, app.js/ts, vendored topbar
- `phx.install.assets.bun` — bun hex dep, app.js/ts, package.json with
  workspace deps + npm packages (topbar, tailwindcss)
- `phx.install.assets.tailwind` — app.css, dynamically composes
  bundler-specific runner via `phx.install.assets.tailwind.#{bundler}`
- `phx.install.assets.tailwind.esbuild` — tailwind hex package runner
- `phx.install.assets.tailwind.bun` — bun css profile runner

Adding support for a new bundler requires implementing two tasks
(`phx.install.assets.<name>` and `phx.install.assets.tailwind.<name>`)
with no changes to existing files.
@LostKobrakai

Copy link
Copy Markdown

npm workspace deps

I'm not 100% sure, but I used file:{path} dependencies with phoenix_vite and it made bun fetch and use devDependencies of the packages under ../deps - which is generally not what you want. I only notices it because I installed playwright for phoenix_test and it never used the latest version I needed. Turns out live_view uses playwright as a dev dependency and I always got their version.

@LostKobrakai

Copy link
Copy Markdown

See LostKobrakai/phoenix_vite#21 for small amouts of context :D

@jimsynz

jimsynz commented Mar 29, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded — composable architecture extracted without bun support into a separate PR.

@jimsynz jimsynz closed this Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants