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:

  • name
  • version
  • private
  • description
  • tagline: Fuz extension, like description but snappier
  • glyph: Fuz extension, emoji or character icon
  • logo: Fuz extension, logo image path
  • logo_alt: Fuz extension, logo alt text
  • license
  • homepage
  • repository
  • funding
  • exports

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; }