Add a JavaScript library
You'll add Chart.js with fsr add, draw a chart with it and see how FSR vendors the library and names it in the import map. Then you'll hit the missing-declarations failure and fix it.
Before you start
Install from crates.io. You need no Node and no package manager.
cargo install snapfire_compiler
cargo install snapfire_fsr_cli
fsr --version
Every command and screenshot on this page was captured with fsr 0.x.
Add it#
One file landed in app/vendor/chart.js/. The file is committed, so anyone who clones the repo already has the library.
fsr add also wrote the import map for you:
That map is what the browser uses to resolve import { Chart } from "chart.js". It is also a build-time allowlist: a bare import with no entry fails the build instead of 404ing in someone's browser.
Add a subpath#
Chart.js wants its auto-registering entry, which is a separate specifier. Ask for it by name:
Now import { Chart } from "chart.js/auto" resolves.
Use it in a browser island#
A chart needs a canvas and a layout pass, so this one belongs in the browser. That's the other island mode from 020.
;
;
Give it a page. The loader returns the figures:
;
The page places the chart as a browser island, with no mode, because useEffect and a live canvas are exactly what server mode cannot do:
;
;
;
when="visible" means the module isn't fetched until the chart scrolls into view. The page around it stays server-rendered.
Where the types came from#
FSR pulled the declarations out of the published package and wrote them under app/types/. Those are for your editor and for tsc and are never shipped. types/ is gitignored, so a fresh clone runs fsr types once.
A package with no declarations#
Try adding a package that publishes no usable declarations:
The build refuses, because every package in the import map must have declarations, so an untyped import can't quietly become any across your codebase.
Either remove the package or declare the part of it you actually use. The second takes about four lines:
;
;Save it as app/types/date-fns/index.d.ts and build again:
The date-fns row now has a path and no version, which marks those declarations as yours and not the registry's.
Mark a library external#
If a library should come from the page that embeds your component rather than from your bundle, mark it external:
The bundle then imports react instead of carrying it. The embedding page supplies it.