A package written on cssints ships JavaScript that still has the attribute, and its .d.ts. The app that installs it evaluates the package with its own engine: one sheet, the app's browserslist and themes, and a token, a kernel or an @property of the package is made once however many modules use it. Nothing is declared: the engine recognises a file by with { type: "cssints" }, the same marker as in app code.
// src/index.ts of the library
import { bg, cn, cv, hover, p } from "cssints" with { type: "cssints" };
import { t } from "./tokens.ts" with { type: "cssints" };
export { t };
export const card = cn(p(4), bg(t.color.brand));
export const button = cv({ base: cn(p(2), hover(bg("#1d4ed8"))) });// in the app: the style is a class string, the token is imported with the attribute to be used or themed
import { createGlobalTheme } from "cssints" with { type: "cssints" };
import { button, card } from "my-ui";
import { t } from "my-ui" with { type: "cssints" };
createGlobalTheme(t, ".dark", { color: { brand: "#ef4444" } });vp pack), with cssints external and dts: true. tsdown keeps the import attributes, so there is no option to set. It also merges import { cx } from "cssints" into the attributed import of the same module; the engine reads cx as runtime wherever it is written, so that is fine. The built .d.ts types button as (props?: …) => string, with the props of its variants. Do not minify, bundle or transform the JS further with a tool that drops import attributes, and do not bundle cssints into it.cssints in peerDependencies (the app needs it to build; a library that imports it must list it), the JS with the attributes, the .d.ts (it types cssints members as class strings and tokens as tokens, so the app is checked across the boundary), and no .css file: the library has no sheet of its own.cssints() plugin has evaluated it, so an app without cssints cannot use it. Pre-compiled output (class strings plus a sheet fragment for apps without cssints) is not supported yet; it waits for a first user.cssints/vite reads the package.json of the app and of each of its dependencies, and for a dependency that lists cssints it adds the package to optimizeDeps.exclude (the dev optimizer would pre-bundle it with esbuild and drop the attributes) and to ssr.noExternal (the engine's runner would otherwise load it as native Node, which does not know the attribute). This is a few file reads at startup, one per dependency, and nothing else. A package that is only a dependency of another package is not found; add it to the app's own dependencies (or to those two options)./node_modules/…/index.js with the classes replaced. They are never watched, so a package does not change during vite dev: restart the server after reinstalling it.