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

@ketvietlab/ketjs-view-tools

v0.6.1

Published

Static-site development and build tools for ketjs-view.

Readme

@ketvietlab/ketjs-view-tools

Static-site tooling for @ketvietlab/ketjs-view. It renders marker-free page HTML, bundles CSS and JavaScript, and preserves hydration markers only inside explicit islands. Its dependencies are ketjs-view, esbuild, and acorn with acorn-jsx for the optional JSX compiler; it does not install the server framework, database adapters or service SDKs.

Use npm create @ketvietlab/view@latest my-site to start a project, then run npm run dev.

Pages and content collections

A page module exports definePage({ head, view }). For Markdown or other build-time data, export a nonempty definePages() collection. Every collection entry requires an explicit, unique, safe path; filename routing still works for single pages. Async content can be loaded before exporting it.

// File: my-site/src/pages/guides.tsx
import { definePages } from '@ketvietlab/ketjs-view-tools'

const guides = [{ path: '/docs/start/', title: 'Start', summary: 'Build your first site.' }]
export default definePages(guides.map(guide => ({
  path: guide.path,
  head: { title: guide.title },
  view: () => <main><h1>{guide.title}</h1><p>{guide.summary}</p></main>,
})))

Configure TypeScript with jsx: "react-jsx" and jsxImportSource: "@ketvietlab/ketjs-view". The standard ket-view check, ket-view build, ket-view dev and ket-view preview commands handle these collections; consumers do not need their own HTML generation loop.

Document metadata

head accepts title, description, lang, links, meta and structuredData. Each meta entry uses either name (ordinary metadata) or property (Open Graph). JSON-LD objects are serialized into the document head with HTML-sensitive characters escaped; their contents cannot close the script element. Supply honest, page-specific schema data.

Use head.scripts: [{ src: '/theme-init.js' }] for an external classic script that must run before styles and the first body paint, such as applying a saved theme preference. Optional type: 'module' and defer: true retain normal browser scheduling; neither is implicit. Head scripts are separate from the automatically bundled island entry.

// File: my-site/src/pages/index.tsx
import { definePage } from '@ketvietlab/ketjs-view-tools'

export default definePage({
  head: {
    title: 'My site',
    description: 'Guides for my project.',
    links: [{ rel: 'canonical', href: 'https://example.com/' }],
    meta: [{ property: 'og:title', content: 'My site' }],
    structuredData: [{ '@context': 'https://schema.org', '@type': 'WebSite', name: 'My site', url: 'https://example.com/' }],
  },
  view: () => <main><h1>My site</h1></main>,
})

Islands and assets

Register island modules in defineConfig({ islands: { counter: 'src/islands/counter.tsx' } }) and place them with island(name, factory, props, options). Props must be JSON serializable. Choose identity with options.key, a list of prop names; use key: [] for a singleton identified by its island name. Omitting it retains the default full-props identity for compatibility.

Styles listed in the config are bundled, including referenced font and image assets. Supported file loaders cover WOFF/WOFF2, TTF/OTF, SVG, PNG, JPEG and WebP. public/ files are copied unchanged. Escaped code samples that mention an island host do not require an island registry entry; live hosts do.

Compile JSX

defineConfig({ compileJsx: true }) compiles each static subtree of intrinsic JSX elements into one html template for both the page render and the island bundle, which must agree for hydration. The markup is unchanged; anything a template cannot express exactly stays runtime JSX. Other builds can use ketJsxPlugin() with esbuild or transformKetJsx(source) per module.

Build this package independently

# Run from: repository root
npm run build --workspace @ketvietlab/ketjs-view
npm run build --workspace @ketvietlab/ketjs-view-tools
node --test packages/ketjs-view-tools/test/page-collections.test.mjs

These package builds compile only the standalone view dependency chain. They do not run the core framework build or the repository-wide test suite.