# SnapFire FSR > SnapFire FSR serves TypeScript web apps written with React, Vue, Tera or web components from one Rust binary, with no JavaScript engine on the serving path. Independent teams deploy their own sites into one host that shares the layout, session and store. Each link below is the Markdown source of a page on this site. The same page without `.md` is its HTML. ## Guide - [What fsr is made of](https://snapfirers.com/fsr/the_guide/000-what-fsr-is-made-of.md): What is fsr, who is it for, what does it refuse to do and what do its terms mean in terms you already know? - [Calling a service without a client](https://snapfirers.com/fsr/the_guide/001-one-contract-no-client-code.md): How does a loader call a service it has never seen a client for, with the editor knowing the types and the runtime refusing a bad call? - [How loaders and actions are lowered](https://snapfirers.com/fsr/the_guide/002-a-body-is-data.md): Why is a loader read rather than run, what happens to one the build cannot read and why does the report always say where a body runs? - [Server rendering without a JavaScript engine](https://snapfirers.com/fsr/the_guide/003-rendered-where-it-is-cheapest.md): How does a React page arrive as HTML from a server that has no JavaScript engine and what does the browser do with it? - [Server components without React Server Components](https://snapfirers.com/fsr/the_guide/004-server-components-without-rsc.md): SnapFire FSR renders components on the server, streams a tree, mounts client modules into it and calls server functions by id. React Server Components do… - [Routes, loaders and pages](https://snapfirers.com/fsr/the_guide/100-routes-loaders-and-pages.md): How does a directory become a route, where does its data come from, what does its page receive and what happens when the user clicks a link? - [Actions and the session](https://snapfirers.com/fsr/the_guide/101-actions-and-the-session.md): How does the browser change something, how is the input typed, where does the session live and what stops an empty cart from reaching the order service? - [Components the server renders](https://snapfirers.com/fsr/the_guide/102-components-the-server-renders.md): What may a page or component say so that the server can render it, what happens to the parts only the browser can run and how do you know which is which? - [Testing a body and a page](https://snapfirers.com/fsr/the_guide/103-testing-a-body.md): How do you test a loader, an action or a page without a backend, without Node and without the test running somewhere the code does not? - [Islands in another framework](https://snapfirers.com/fsr/the_guide/104-islands-in-another-framework.md): How does a Vue component end up on a page the server rendered, what does the build do with a .vue file and what does an application that has no React in it… - [Applications without a framework](https://snapfirers.com/fsr/the_guide/105-no-framework-at-all.md): What does an fsr application look like with no component framework in it, where does the interactivity go and how does a region talk to the server without a… - [Two frameworks on one page](https://snapfirers.com/fsr/the_guide/106-two-frameworks-on-one-page.md): What does it actually take to run React and Vue in the same document, what do they share and what does it cost? - [Moving tests from Jest or Vitest](https://snapfirers.com/fsr/the_guide/107-moving-tests-from-jest-or-vitest.md): You have a suite written for Jest or Vitest with Testing Library. What changes when it runs under fsr test? - [Images and fonts](https://snapfirers.com/fsr/the_guide/108-images-and-fonts.md): For app developers. How an image a component imports becomes a served in the sizes a page needs, how a font under fonts/ reaches the page with no… - [Tailwind and themes](https://snapfirers.com/fsr/the_guide/109-tailwind-and-themes.md): For app developers. How a stylesheet that imports Tailwind gets its utilities from the classes your pages render, what the build says about a class it cannot… - [MDX and markdown](https://snapfirers.com/fsr/the_guide/110-mdx-and-markdown.md): For app developers. How a page or a piece of content is written in MDX or plain markdown, how the build lowers it like any other component, how a page picks a… - [Values the server and browser disagree on](https://snapfirers.com/fsr/the_guide/111-values-the-server-and-browser-disagree-on.md): What happens to a component that reads the local clock, the time zone, Math.random() or window (values the server and the browser would compute differently)… - [The stock host and its configuration](https://snapfirers.com/fsr/the_guide/200-the-stock-host-and-its-configuration.md): What runs an fsr application when nobody has written a server, where does it read its configuration and how do you know what it decided? - [Graduating to Rust](https://snapfirers.com/fsr/the_guide/201-graduating-to-rust.md): How does one loader, action or route move from TypeScript into Rust without the rest of the application noticing and what stops that from happening by accident? - [Services and transports](https://snapfirers.com/fsr/the_guide/202-services-and-transports.md): What happens between a body saying services.shopping.listProducts({}) and bytes leaving the process, who checks what and why application code can never see a… - [Sessions and identity](https://snapfirers.com/fsr/the_guide/203-sessions-and-identity.md): Where does the session a body reads actually live, who is the request and where does a login go? - [Reloading in place](https://snapfirers.com/fsr/the_guide/204-reloading-in-place.md): What changes when the application changes under a running host and what does not? - [Sites](https://snapfirers.com/fsr/the_guide/205-sites.md): How does a team own its part of the product, deploy it on its own schedule and still share the header, the sign-in and the navigation with everyone else? - [What a request did](https://snapfirers.com/fsr/the_guide/206-what-a-request-did.md): When a page is slow or wrong, how do you find out what actually happened, without wiring a collector first? - [The build and the dev loop](https://snapfirers.com/fsr/the_guide/300-the-build-and-the-dev-loop.md): What does fsr build produce, why is none of it committed and what does fsr dev do when a file changes? - [Dependencies without npm](https://snapfirers.com/fsr/the_guide/301-dependencies-without-npm.md): How does React get into the browser when there is no node_modules, where do the types for it come from and what changes when a team already has its own module… - [Imports and aliases](https://snapfirers.com/fsr/the_guide/302-imports-and-aliases.md): Why does a page write @src/ui/Header rather than ../../src/ui/Header, who understands that and what does the browser see? - [The deploy tree](https://snapfirers.com/fsr/the_guide/303-the-deploy-tree.md): What do you copy to a server and how does what it serves there stay the same as what it served under fsr dev? - [Checking a deployment](https://snapfirers.com/fsr/the_guide/304-checking-a-deployment.md): What is wrong with an application that starts, serves and answers, but does not do what its configuration says it does? - [Third-party scripts](https://snapfirers.com/fsr/the_guide/305-third-party-scripts.md): Where do an analytics tag, a consent banner, a font and a favicon go, given that an application has no document template, no head component and writes no… - [What a page asks other origins for](https://snapfirers.com/fsr/the_guide/306-what-a-page-asks-other-origins-for.md): When a visitor opens one of your pages, which requests leave for hosts other than yours? How do you keep one of them on your own origin when privacy or… - [The parts bin](https://snapfirers.com/fsr/the_guide/900-the-parts-bin.md): Every block in every crate, one line each, sorted by what you would be looking for. The chapters explain how the pieces fit; this is the index for when you… ## Tutorials - [Build your first page](https://snapfirers.com/fsr/learn/010-build-your-first-page.md): You'll scaffold an app, change its loader to return some data and put that data on a page. A Rust binary serves it. - [Build a counter](https://snapfirers.com/fsr/learn/020-build-a-counter.md): You'll add a working button. The browser downloads no component code for it. Clicking it sends the event to Rust, Rust runs the handler and sends back the… - [Add a working cart](https://snapfirers.com/fsr/learn/030-add-a-working-cart.md): You'll build a cart whose contents live in the session on the server. Adding an item is one typed call from the browser. The server holds the only copy of… - [Cache loaders and renders](https://snapfirers.com/fsr/learn/100-cache-loaders-and-renders.md): You'll make pages fast by letting FSR do the caching. FSR works out which routes read nothing of the request, renders those once and answers them from a… - [Prerender a blog at build time](https://snapfirers.com/fsr/learn/110-prerender-a-blog-at-build-time.md): You'll build a three-post blog where every post is a file on disk before the first request arrives. A post that isn't in the set still renders live, so a new… - [Find out what won't compile](https://snapfirers.com/fsr/learn/120-find-out-what-wont-compile.md): FSR turns your TypeScript into data a Rust host runs. Some code can't be expressed that way. You'll write some, read what the build says about it and see the… - [Validate a form](https://snapfirers.com/fsr/learn/130-validate-a-form.md): You'll build a sign-up form that rejects bad input, comes back with the message beside the field and leaves everything the visitor typed exactly where it was… - [Stream a slow page](https://snapfirers.com/fsr/learn/140-stream-a-slow-page.md): You'll take a page that waits four seconds on a recommendation service and make the rest of it arrive immediately, with the slow region filling in where it… - [Share state with the store](https://snapfirers.com/fsr/learn/150-share-state-with-the-store.md): You'll build an order page whose islands share state the way signals would: a badge in the header and a stepper on the page read one value, a picker writes… - [Add share cards](https://snapfirers.com/fsr/learn/160-add-share-cards.md): You'll give each page of a small recipe site its own share card: the picture a chat app or a social site shows when someone pastes the link. Each card is… - [Port async components from Next.js](https://snapfirers.com/fsr/learn/170-port-async-components-from-next-js.md): You'll write a report page the way Next's App Router teaches, with an async component that awaits its data. fsr will refuse it and tell you where the await… - [Write your islands in Vue](https://snapfirers.com/fsr/learn/200-write-your-islands-in-vue.md): You'll start a fresh app, point it at Vue and write a single-file component the server renders and the browser hydrates. Vue is the only framework in the… - [Write islands as web components](https://snapfirers.com/fsr/learn/210-write-islands-as-web-components.md): You'll build a tool library. The pages are the same lowered templates as any other FSR app. The interactive bits are custom elements, which the browser… - [React and Vue on one page](https://snapfirers.com/fsr/learn/220-react-and-vue-on-one-page.md): You'll put a React island and a Vue island in the same document, have them share one piece of state, then navigate between a page whose island is Vue and a… - [Write your pages in Tera](https://snapfirers.com/fsr/learn/230-write-your-pages-in-tera.md): You'll build a noticeboard whose pages are Tera templates the host renders straight from the file. The routing, the loaders and the prerendering are the same… - [Style an app with Tailwind](https://snapfirers.com/fsr/learn/240-style-an-app-with-tailwind.md): You'll style a status page with Tailwind utilities. Tailwind CSS v4 is built into the bundler and the build hands it the exact list of classes your pages… - [Run one app on two domains](https://snapfirers.com/fsr/learn/300-run-one-app-on-two-domains.md): You'll make one binary answer for two host names and serve something different on each. The loader reads which domain it was asked on. A forged Host header… - [Put a docs site inside your app](https://snapfirers.com/fsr/learn/310-put-a-docs-site-inside-your-app.md): You'll mount a whole second FSR application inside the first one, at a prefix, sharing its navbar and its theme. The two applications can live in separate… - [Port a Next.js route](https://snapfirers.com/fsr/learn/320-port-a-next-js-route.md): You'll port a Next product page to FSR: the data fetch, the server action and the client component. You end up with a running app whose API client, request… - [Add a JavaScript library](https://snapfirers.com/fsr/learn/330-add-a-javascript-library.md): 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… - [Add Google Analytics with a consent banner](https://snapfirers.com/fsr/learn/340-add-google-analytics-with-a-consent-banner.md): This continues the shop app from 330. You will add a cookie consent banner, load Google Analytics only after the analytics category is accepted and keep the… - [Protect a route](https://snapfirers.com/fsr/learn/350-protect-a-route.md): You'll put a page behind a sign-in, turn an anonymous visit into a redirect and read who the visitor is from a loader. The check is one file and it runs… - [Add light and dark themes](https://snapfirers.com/fsr/learn/360-add-light-and-dark-themes.md): You'll add light and dark that is correct in the first byte the server sends. A visitor who never chooses gets their system's setting. One who chooses keeps… - [Accept a file](https://snapfirers.com/fsr/learn/370-accept-a-file.md): You'll take a file from a form, check it before it goes anywhere and hand the bytes on. It works with JavaScript switched off. - [Embed a video](https://snapfirers.com/fsr/learn/380-embed-a-video.md): You'll put two YouTube videos on a page. The server renders each one as a still with a play button. The player only loads for the one a visitor actually… - [Animate page changes with view transitions](https://snapfirers.com/fsr/learn/390-animate-page-changes-with-view-transitions.md): You'll build a grid of colors where clicking a tile grows it into the full swatch on the next page. Back shrinks it home again. It's the browser's own View… - [Keep page state across navigation](https://snapfirers.com/fsr/learn/395-keep-page-state-across-navigation.md): You'll build a page with a notes field, a packing checklist and a list of hikes. Open a hike, press Back and the page comes back the way you left it: the… - [Test a loader](https://snapfirers.com/fsr/learn/400-test-a-loader.md): You'll test a loader with fsr test. The test runs your loader through the same interpreter that serves requests, with its services stubbed, so nothing else… - [Ship it](https://snapfirers.com/fsr/learn/410-ship-it.md): You'll turn an app into a directory and a binary you copy to a server. First you'll run the checks that catch problems that only appear in production. - [Debug a page in production](https://snapfirers.com/fsr/learn/420-debug-a-page-in-production.md): You'll read a request back as one tree that shows which loader waited on which service, what ran at the same time and which cache answered. You'll do it first… - [Make a page fast](https://snapfirers.com/fsr/learn/430-make-a-page-fast.md): 420 reads a trace to find out what a request did. This tutorial uses the trace to find which part of a slow page to cut and to check that the cut worked. The… - [Find broken links](https://snapfirers.com/fsr/learn/440-find-broken-links.md): A page can render correctly while some of its requests fail. You'll learn what the deploy tree actually serves, why development never shows you the difference… - [Set a content security policy](https://snapfirers.com/fsr/learn/450-set-a-content-security-policy.md): You'll write a Content-Security-Policy, find out what it blocks before it blocks anything, read each violation in the dev panel and see why nonces don't work… - [Move a loader into Rust](https://snapfirers.com/fsr/learn/500-move-a-loader-into-rust.md): You'll take one loader out of TypeScript and answer it from Rust. The page, the route and the tests don't change. At the end you'll load the page and see your… - [Add FSR to an existing Rust service](https://snapfirers.com/fsr/learn/510-add-fsr-to-an-existing-rust-service.md): The FSR host is a tower::Service, so you can mount it inside a binary you already have, with your own runtime, middleware and listener. - [Serve Tera templates from Rust](https://snapfirers.com/fsr/learn/520-serve-tera-templates-from-rust.md): You'll build a notes board that renders from Tera templates, with its plan, loader and action written in Rust. At the end you'll add a note through a form… ## Docs - [Introduction](https://snapfirers.com/fsr/docs/000-introduction.md): These pages are the practical documentation for SnapFire FSR. They cover what it is, how to get an application running and how the pieces fit once you have… - [What SnapFire FSR is](https://snapfirers.com/fsr/docs/001-what-snapfire-fsr-is.md): FSR is a full-stack runtime for TypeScript applications that runs on Rust, with no JavaScript engine in the serving path. - [Getting started](https://snapfirers.com/fsr/docs/100-getting-started.md): You need Rust and nothing else. The build installs the two binaries it uses. - [The application model](https://snapfirers.com/fsr/docs/101-the-application-model.md): A directory under app/routes/ is a route only when it holds a page.tsx or a page.tera. The path is the directory path. - [Data and rendering](https://snapfirers.com/fsr/docs/102-data-and-rendering.md): Prerendered. A route whose loader reads nothing request-specific (no query, no session, no identity, no clock) can be rendered once at build time and answered… - [Islands and hydration](https://snapfirers.com/fsr/docs/200-islands-and-hydration.md): Most components never reach the browser. The build lowers them and the host renders them, so they only cost markup. A component qualifies when it is a… - [Actions and the session](https://snapfirers.com/fsr/docs/201-actions-and-the-session.md): A loader reads data and an action writes it. An action lives in actions.ts beside the page. It is declared with action instead of just exported, so the build… - [Sites](https://snapfirers.com/fsr/docs/202-sites.md): Add a [site] block to a configuration and the application becomes a site: every id the build emits is prefixed with its name and every route sits under its… - [What a request did](https://snapfirers.com/fsr/docs/203-what-a-request-did.md): A log line records one fact. Ten log lines from one request have to be reassembled by hand, interleaved with every other request in flight. A trace records… - [Vue, Web Components, htmx and Tera](https://snapfirers.com/fsr/docs/204-other-frameworks-and-none.md): A placement carries a module id and nothing else. The server writes around whatever it rendered there; the… - [The parts bin](https://snapfirers.com/fsr/docs/300-the-parts-bin.md): Make a directory under app/routes/ matching the path and put a page.tsx in it. routes/pricing/ serves /pricing; routes/product/[id]/ serves /product/{id} with… - [Diagrams](https://snapfirers.com/fsr/docs/400-diagrams.md): The host matches the route against the plan, evaluates the lowered loader as interpreted IR, walks the component tree and writes HTML. No JavaScript engine is… ## Optional - [Compared](https://snapfirers.com/fsr/compare): FSR next to Next.js, Nuxt, SvelteKit, Astro, Remix 3, Leptos and Dioxus.