vite_plugin_pkg_json #
vite_plugin_pkg_json is a Vite plugin that serves a publish-safe subset
of your package.json as the virtual module 'virtual:pkg.json'. The default export is typed PkgJson from fuz_util, and contains
package identity plus Fuz extension fields, with everything else excluded.
The plugin strips package.json to the allowlist and serves only that, so info
like name/version/repository and the Fuz extension fields like logo are available to your
code. The docs system around the content you're reading relies on it. Importing the root package.json directly instead inlines the whole file -- scripts, dependencies, private config -- into the client bundle and trips SvelteKit's server.fs.allow on a cold HMR reload; serving the curated subset avoids both.
Setup #
Register the plugin, vite_plugin_pkg_json.ts:
// vite.config.ts
import {defineConfig} from 'vite';
import {sveltekit} from '@sveltejs/kit/vite';
import {vite_plugin_pkg_json} from '@fuzdev/fuz_ui/vite_plugin_pkg_json.js';
export default defineConfig({
plugins: [sveltekit(), vite_plugin_pkg_json()],
}); The plugin uses enforce: 'pre' so any order works. For TypeScript it requires
ambient declarations, like in src/app.d.ts:
// src/app.d.ts
declare module 'virtual:pkg.json' {
import type {PkgJson} from '@fuzdev/fuz_util/pkg_json.js';
const pkg_json: PkgJson;
export default pkg_json;
} You may then import the default export anywhere in client or server code:
import pkg_json from 'virtual:pkg.json';Usage #
fuz_ui has optional patterns that leverage the feature. One example is adding SiteState at the root layout, so glyph and repo_url come from package.json instead of being
hardcoded:
// +layout.svelte or some other root
import pkg_json from 'virtual:pkg.json';
import {SiteState, site_context} from '@fuzdev/fuz_ui/site.svelte.js';
// glyph + repo_url derive from pkg_json.glyph and pkg_json.repository
site_context.set(new SiteState({pkg_json})); It's also the curated pkg_json half of a LibraryJson rendered by LibraryDetail. The fuz_ui docs pattern combines it with the analyzed modules from virtual:svelte-docinfo (svelte-docinfo.fuz.dev):
// src/routes/library.ts
import {library_json_from_modules} from '@fuzdev/fuz_util/library_json.js';
import {modules} from 'virtual:svelte-docinfo';
import pkg_json from 'virtual:pkg.json';
export const library_json = library_json_from_modules(pkg_json, modules);What gets served #
By default the plugin keeps only the keys in pkg_json_keys, including package identity values and some Fuz extension fields. Everything else is
dropped:
nameversionprivatedescriptiontagline: Fuz extension, like description but snappierglyph: Fuz extension, emoji or character iconlogo: Fuz extension, logo image pathlogo_alt: Fuz extension, logo alt textlicensehomepagerepositoryfundingexports
Custom keys #
The set of picked fields defaults to pkg_json_keys, and you can extend or replace them:
// src/routes/pkg_json_keys.ts — one shared const for all three sites
import {pkg_json_keys} from '@fuzdev/fuz_util/pkg_json.js';
export const custom_keys = [...pkg_json_keys, 'keywords'] as const; Because library_json_from_modules re-strips at runtime, the same list must reach
all three places (the plugin, that runtime call, and the virtual:pkg.json ambient type), or the extras get dropped:
// vite.config.ts
vite_plugin_pkg_json({keys: custom_keys});
// src/routes/library.ts
library_json_from_modules(pkg_json, modules, custom_keys); For type safety, widen the src/app.d.ts ambient type to match -- the same custom_keys const drives it via Pick over PackageJson:
// src/app.d.ts
declare module 'virtual:pkg.json' {
import type {PackageJson} from '@fuzdev/fuz_util/package_json.js';
import type {custom_keys} from '$routes/pkg_json_keys.js';
const pkg_json: Pick<PackageJson, (typeof custom_keys)[number]>;
export default pkg_json;
}