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

@frontierjs/config

v0.1.6

Published

The tooling opinion a FrontierJS app extends in one line — tsconfig and Biome, no source of its own

Readme

@frontierjs/config

The tooling opinion a FrontierJS application extends in one line. No source, no binary, no runtime — three files and the reasoning behind them.

bun add -d @frontierjs/config @biomejs/biome typescript

fli new adds it for you. This package exists so that the opinion is a dependency and not a copy: a rule improved here reaches every app that already exists, where a file the scaffold wrote is frozen at the moment it was written.

What an app extends

// tsconfig.json
{ "extends": "@frontierjs/config/tsconfig", "include": ["api/**/*", "web/**/*"] }
// biome.json
{ "extends": ["@frontierjs/config/biome"] }

.editorconfig is the exception, because EditorConfig has no extends mechanism — the scaffold writes the text, and this package holds the original it was written from.

There is no formatter, and that is a decision

biome.json ships "formatter": { "enabled": false }.

FrontierJS aligns columns where a run of lines is parallel — imports, object literals, const blocks:

import { withDb }  from './core/hooks.ts'
import { env }     from './core/env.ts'

Prettier, Biome and dprint all collapse that to a single space, and none of the three can express it — an opinionated formatter's whole proposition is that whitespace carries no information, and this rule says it carries some. The framework's canonical files are written that way and so is the code fli new generates, so the first format run of any of the three would rewrite the app it had just scaffolded.

The rejected third path is a biome-ignore format: comment above every aligned run. That is a comment whose only reader is a tool, in a house whose rule is that a comment must be load-bearing or deleted.

"assist": { "enabled": false } comes with it for the same reason: Biome's import sorting reorders an aligned import block, which is a format change wearing a lint rule's clothes.

What the linter is for, then

Correctness, security and the suspicious-pattern set — plus accessibility, which reaches index.html. The style, complexity and performance groups are off. With the formatter refused, a linter that argues about style is a formatter that cannot fix anything.

noExplicitAny is off because a framework boundary types values it did not create; noEmptyInterface is off because an empty exported interface is the slot an app augments by declaration merging, and its autofix (a type alias) closes the slot; noImplicitAnyLet is off because TypeScript types a bare let by control flow and tsc already grades the result; noUnusedVariables is a warning rather than an error because a destructure that drops a key is a legitimate shape. useIterableCallbackReturn skips forEach: its return value is discarded by the language, so items.forEach(i => seen.add(i)) is not a bug, while a map or filter callback that forgets to return is.

What it cannot see

Biome reads neither .mesa nor .lite, and neither can ESLint or dprint without a hand-written processor. Those two files are where an FJS application's real mistakes live, which draws the boundary this package is one half of:

A linter owns generic JavaScript correctness. fli check owns everything derived from the schema — a model name that is not PascalCase singular, a resource file that is not named for its noun, a Vite config without strictPort, the body tag mentioned inside a comment. Neither reimplements the other, and the VS Code extension surfaces both rather than implementing either.

The reason is not tooling immaturity: doctor-class questions are cross-file. Does this resource name resolve to a model? cannot be answered from the file it appears in, and that is where every entry in the hazard catalog lives.

A scaffolded app's bun run check runs fli check first, because it is the half a linter cannot reach.

Versioning

Loosening a rule is a patch. Adding one is a minor, and it can fail an app's CI on code that has not changed — which is the price of the config being a dependency, and the reason it is worth paying only for rules that catch bugs.