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

@structcms/core

v0.1.2

Published

Core modeling, validation, and types for StructCMS

Downloads

286

Readme

@structcms/core

Core modeling, validation, and types for StructCMS. Provides code-first content schema definitions, a registry for section/page type registration, type inference, and a framework-agnostic section renderer.

For architectural context, see ARCHITECTURE.md (Layer 1: Modeling, Layer 2: Registry, Layer 7: Rendering).

← Back to main README

Installation

npm install @structcms/core

Quick Start

import { defineSection, fields, createRegistry } from '@structcms/core';

// Define a section
const HeroSection = defineSection({
  name: 'hero',
  fields: {
    title: fields.string(),
    subtitle: fields.text(),
    image: fields.image(),
  },
});

// Create a registry
const registry = createRegistry({
  sections: [HeroSection],
});

// Get a section at runtime
const hero = registry.getSection('hero');

File Structure

packages/core/
├── src/
│   ├── index.ts                  # Public exports
│   ├── define-section.ts         # defineSection() API
│   ├── define-page-type.ts       # definePageType() API
│   ├── define-navigation.ts      # defineNavigation() API
│   ├── fields.ts                 # Field type helpers (string, text, richtext, image, etc.)
│   ├── registry.ts               # createRegistry() API
│   ├── section-renderer.ts       # createSectionRenderer() API
│   ├── types.ts                  # All type definitions
│   ├── *.test.ts                 # Unit tests (co-located)
├── package.json
├── tsconfig.json
└── tsup.config.ts                # Build config

Key Concepts

Code-First Modeling

Content schemas are defined in TypeScript using Zod, not in a GUI. The fields.* helpers attach metadata that @structcms/admin uses for dynamic form generation. See src/fields.ts.

Registry Pattern

The registry collects all section, page type, and navigation definitions at startup and provides runtime access via getSection(), getPageType(), etc. Host projects create one registry and pass it to @structcms/admin. See src/registry.ts.

Type Inference

InferSectionData<T> extracts the TypeScript data type from a SectionDefinition, enabling fully typed frontend components without manual type definitions. See src/types.ts.

API Reference

Modeling

  • defineSection({ name, fields }) — Define a section with Zod schema fields. Returns a typed SectionDefinition.
  • definePageType({ name, allowedSections }) — Define which sections a page type allows.
  • defineNavigation({ name, schema? }) — Define a navigation structure with optional custom item schema.

Field Helpers

  • fields.string() — Short text (single line input)
  • fields.text() — Long text (textarea)
  • fields.richtext() — Rich text (WYSIWYG editor, outputs HTML)
  • fields.image() — Image reference (media ID or URL)
  • fields.reference() — Page reference (slug or ID)
  • fields.array(itemSchema) — Array field with add/remove/reorder
  • fields.object(shape) — Nested object field

Each field helper wraps a Zod schema with metadata used by @structcms/admin for dynamic form generation.

Field Utilities

  • getFieldMeta(schema) — Extract FieldMeta (including fieldType) from a Zod schema. Returns null if no metadata is present.
  • isFieldType(schema, fieldType) — Check whether a Zod schema has a specific field type (e.g. 'richtext').

Registry

  • createRegistry({ sections, pageTypes?, navigations? }) — Creates a registry instance with methods:
    • getSection(name) — Get a section definition by name
    • getAllSections() — Get all registered sections
    • getPageType(name) — Get a page type definition by name
    • getAllPageTypes() — Get all registered page types
    • getNavigation(name) — Get a navigation definition by name
    • getAllNavigations() — Get all registered navigations

Rendering

  • createSectionRenderer({ components, fallback? }) — Maps section types to components. Framework-agnostic (React, Preact, Vue, or plain functions).

Type Utilities

  • InferSectionData<T> — Extract the data type from a SectionDefinition
  • SectionComponentProps<T> — Props type for section components ({ data: T, sectionKey: string | number })

Dependencies

| Package | Purpose | |---------|----------| | zod | Schema definition and validation (peer dependency ^3.23.0) |

Development

# Run tests (watch mode)
pnpm test

# Run tests once
pnpm test run

# Build
pnpm build

# Type check
pnpm typecheck

← Back to main README