npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@getforma/build

v0.1.7

Published

[![npm](https://img.shields.io/npm/v/@getforma/build)](https://www.npmjs.com/package/@getforma/build) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Readme

@getforma/build

npm License: MIT

Production build pipeline for FormaJS applications. Handles esbuild bundling, CSS generation, content hashing, Brotli/gzip compression, asset manifest generation, SSR IR emission, and WASM compilation — all from a single config.

This replaces writing your own build script. If you're using Vite for development and need a production pipeline with content hashing and SSR, this is the tool.

Install

npm install -D @getforma/build

This installs esbuild automatically. For SSR features (FMIR emission), also install the compiler:

npm install -D @getforma/compiler

Quick Start

// build.ts
import { build } from "@getforma/build";

await build({
  entryPoints: [
    { entry: "src/app.tsx", outfile: "app.js" },
  ],
  routes: {
    "/": { js: ["app"], css: ["app"] },
  },
  outputDir: "dist",
});
npx tsx build.ts

This bundles your app with esbuild, applies the FormaJS compiler transforms, content-hashes all assets, generates Brotli + gzip compressed versions, and writes an asset manifest.

What It Does

| Step | What happens | |------|-------------| | Bundle | esbuild bundles each entry point with JSX transform (jsxFactory: "h") | | Compile | @getforma/compiler transforms h() calls to template() + cloneNode() | | CSS | Runs Tailwind CLI or concatenates CSS files | | Hash | SHA-256 content hash appended to filenames (app.a1b2c3d4.js) | | Compress | Brotli (level 11) + gzip (level 9) for .js and .css | | Manifest | Writes manifest.json mapping source filenames → hashed filenames | | SSR | (Optional) Emits FMIR binary for Rust server-side rendering | | WASM | (Optional) Runs wasm-pack build for the Rust IR walker | | Budget | Warns if route brotli size exceeds threshold (default 200KB) |

Configuration

import { build, type BuildConfig } from "@getforma/build";

const config: BuildConfig = {
  // Required
  entryPoints: [
    { entry: "src/home/app.tsx", outfile: "home.js" },
    { entry: "src/dashboard/app.tsx", outfile: "dashboard.js" },
  ],
  routes: {
    "/": { js: ["home"], css: ["home"] },
    "/dashboard": { js: ["dashboard"], css: ["dashboard"] },
  },
  outputDir: "dist",

  // Optional
  cssEntries: [
    { type: "tailwind", input: "src/app.css", output: "app.css" },
  ],
  fontDir: "src/fonts",              // Copy .woff2 files to dist
  ssr: true,                          // Enable FMIR emission
  ssrEntryPoints: {
    home: "src/home/HomeIsland.tsx",
    dashboard: "src/dashboard/DashboardIsland.tsx",
  },
  wasm: { crateDir: "../crates/forma-ir" },  // Build WASM walker
  budgetThreshold: 200_000,           // Warn at 200KB brotli per route
  formaAlias: "./node_modules/@getforma/core/dist/index.js",
  serverInlined: ["sw.js"],           // Files to keep unhashed copies of
};

await build(config);

Output Structure

dist/
├── home.a1b2c3d4.js         # Content-hashed bundle
├── home.a1b2c3d4.js.br      # Brotli compressed
├── home.a1b2c3d4.js.gz      # Gzip compressed
├── home.e5f6g7h8.css
├── home.e5f6g7h8.css.br
├── dashboard.i9j0k1l2.js
├── home.m3n4o5p6.ir          # FMIR binary (if ssr: true)
├── forma_ir.q7r8s9t0.js      # WASM loader (if wasm configured)
├── forma_ir_bg.u1v2w3x4.wasm # WASM binary
├── inter.woff2                # Copied fonts
├── sw.js                      # Service worker (unhashed copy)
├── manifest.json              # Asset manifest
└── manifest.json.br

Asset Manifest

The manifest maps source filenames to content-hashed filenames:

{
  "version": 1,
  "build_hash": "sha256-of-all-asset-names",
  "assets": {
    "home.js": "home.a1b2c3d4.js",
    "home.css": "home.e5f6g7h8.css",
    "home.ir": "home.m3n4o5p6.ir"
  },
  "routes": {
    "/": {
      "js": ["home.a1b2c3d4.js"],
      "css": ["home.e5f6g7h8.css"],
      "ir": "home.m3n4o5p6.ir",
      "total_size_br": 45230
    }
  }
}

The Rust server (forma-server) reads this manifest to serve assets with correct cache headers and resolve hashed filenames.

When Do You Need This?

| Scenario | Need @getforma/build? | |----------|----------------------| | Learning / prototyping | No — use Vite | | Production with Vite only | No — Vite handles it | | Production with content hashing + compression | Yes | | Rust SSR with forma-server | Yes — emits FMIR + manifest | | Multiple route entry points | Yes — handles multi-page builds |

Compiler vs Build

| | @getforma/compiler | @getforma/build | |---|---|---| | What it is | Vite/esbuild plugins | Full build pipeline | | Use case | Add to existing Vite config | Replace your build script | | Includes compiler? | — | Optional peer dependency (needed for SSR only) | | Content hashing | No | Yes | | Compression | No | Yes (Brotli + gzip) | | Manifest | No | Yes | | SSR IR emission | Plugin only | Integrated | | Install separately? | Yes | Yes (pulls in compiler) |

Part of the Forma Stack

Frontend (TypeScript)

| Package | Description | |---|---| | @getforma/core | Reactive DOM library — signals, h(), islands, SSR hydration | | @getforma/compiler | Vite plugin — h() optimization, server transforms, IR emission | | @getforma/build | This package — bundling, hashing, compression, manifest |

Backend (Rust)

| Package | Description | |---|---| | forma-ir | FMIR binary format — parser, walker, WASM exports | | forma-server | Axum middleware — SSR page rendering, asset serving, CSP headers |

Full Framework

| Package | Description | |---|---| | @getforma/create-app | npx @getforma/create-app — scaffolds a Rust server + TypeScript frontend project |

License

MIT