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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@writely/core

v0.0.4

Published

Beautiful, accessible UI components and theme system for building modern blogs. Includes customizable themes, responsive components, and full TypeScript support.

Downloads

14

Readme

@writely/core

Core schemas, themes, and utilities for the Writely blog platform. Provides the foundation for blog configuration, theme management, and shared utilities used across all Writely packages with comprehensive validation and type safety.

Features

  • Schema Validation: Comprehensive Zod schemas for blog configuration and content validation
  • Theme System: 6 beautiful, customizable themes with responsive layouts and consistent API
  • Type Safety: Full TypeScript support with generated types and runtime validation
  • SEO Schemas: Complete SEO meta tag schemas with Open Graph and Twitter Card support
  • Design System: Global CSS with design tokens, dark mode support, and responsive utilities
  • Utility Functions: Shared utility functions for class names, styling, and common operations
  • Configuration Management: Robust blog configuration with validation and defaults
  • Theme Components: React components for each theme with consistent props and behavior
  • Navigation Schemas: Structured navigation and footer configuration schemas
  • Content Schemas: MDX frontmatter validation with comprehensive field support

Installation

# Install the core package
npm install @writely/core

# Install with TypeScript types
npm install @writely/core @types/react

API

Blog Configuration

import { BlogConfig, BlogConfigSchema, ThemeName } from "@writely/core";

// Blog configuration with full type safety
const config: BlogConfig = {
  title: "My Blog",
  description: "A beautiful blog built with Writely",
  author: "Your Name",
  url: "https://myblog.com",
  language: "en",
  theme: "nova",
  seo: {
    metatags: {
      description: "My blog description",
      keywords: "blog, writely, mdx",
      author: "Your Name",
      "og:title": "My Blog",
      "og:description": "A beautiful blog",
      "twitter:card": "summary_large_image",
    },
  },
  content: {
    postsPerPage: 10,
    defaultLayout: "post",
    defaultAuthor: "Your Name",
    defaultTags: ["blog", "writely"],
  },
};

// Validate configuration at runtime
const validatedConfig = BlogConfigSchema.parse(config);

Theme System

import { ThemeName, getTheme, ThemeComponent } from '@writely/core';

// Available themes
const themes: ThemeName[] = ['nova', 'atlas', 'pulse', 'prism', 'quantum', 'helix'];

// Get theme component
const ThemeComponent: ThemeComponent = getTheme('nova');

// Use theme component
<ThemeComponent config={blogConfig}>
  {children}
</ThemeComponent>

// Import specific theme layouts
import { NovaLayout, AtlasLayout, PulseLayout } from '@writely/core';

// Use theme layout directly
<NovaLayout config={blogConfig}>
  {children}
</NovaLayout>

SEO Schemas

import { SEOMetaTags, SEOMetaTagsSchema } from "@writely/core";

// SEO meta tags with comprehensive support
const seoTags: SEOMetaTags = {
  description: "My blog description",
  keywords: "blog, writely, mdx",
  author: "Your Name",
  "og:title": "My Blog",
  "og:description": "A beautiful blog",
  "og:type": "website",
  "og:url": "https://myblog.com",
  "og:image": "https://myblog.com/og-image.png",
  "twitter:card": "summary_large_image",
  "twitter:site": "@yourusername",
  "twitter:creator": "@yourusername",
  "apple-mobile-web-app-capable": "yes",
  "apple-mobile-web-app-status-bar-style": "default",
  "msapplication-TileColor": "#000000",
};

// Validate SEO tags
const validatedTags = SEOMetaTagsSchema.parse(seoTags);

MDX Frontmatter

import { MDXFrontmatter, MDXFrontmatterSchema } from "@writely/core";

// MDX frontmatter with comprehensive field support
const frontmatter: MDXFrontmatter = {
  title: "My Blog Post",
  description: "A great blog post about Writely",
  date: "2024-01-01",
  author: "Your Name",
  tags: ["blog", "writely", "mdx"],
  draft: false,
  featured: true,
  coverImage: "/images/cover.jpg",
  socialImage: "/images/social.jpg",
  tableOfContents: true,
  comments: true,
  readingTime: true,
  priority: 0.8,
  series: "Getting Started",
  seriesOrder: 1,
  customFields: {
    difficulty: "beginner",
    category: "tutorial",
  },
};

// Validate frontmatter
const validatedFrontmatter = MDXFrontmatterSchema.parse(frontmatter);

Utilities

import { cn } from "@writely/core/lib/utils";

// Class name utility (similar to clsx/classnames with Tailwind merge)
const className = cn(
  "base-class",
  condition && "conditional-class",
  "another-class",
  {
    "object-class": true,
    "disabled-class": isDisabled,
  },
);

Configuration

Blog Configuration Schema

interface BlogConfig {
  // Required fields
  title: string;
  description: string;
  author: string;
  url: string;

  // Optional fields with defaults
  language?: string; // default: "en"
  theme?: ThemeName; // default: "nova"
  themeConfig?: Record<string, any>;

  // SEO configuration
  seo?: {
    metatags?: SEOMetaTags;
    defaultOpenGraph?: {
      type?: string;
      locale?: string;
      siteName?: string;
      images?: string[];
    };
    defaultTwitter?: {
      card?: string;
      site?: string;
      creator?: string;
    };
  };

  // Social media links
  social?: {
    twitter?: string;
    github?: string;
    linkedin?: string;
    facebook?: string;
    instagram?: string;
  };

  // Navigation structure
  navigation?: Array<{
    title: string;
    href: string;
    children?: Array<{
      title: string;
      href: string;
    }>;
  }>;

  // Footer configuration
  footer?: {
    copyright?: string;
    links?: Array<{
      title: string;
      href: string;
    }>;
  };

  // Content configuration
  content?: {
    postsPerPage?: number; // default: 10
    defaultLayout?: string;
    defaultTemplate?: string;
    defaultAuthor?: string;
    defaultCategory?: string;
    defaultTags?: string[];
    defaultCoverImage?: string;
    defaultSocialImage?: string;
    defaultTableOfContents?: boolean; // default: true
    defaultComments?: boolean; // default: true
    defaultReadingTime?: boolean; // default: true
    defaultPriority?: number; // default: 0.5
    defaultDraft?: boolean; // default: false
    defaultFeatured?: boolean; // default: false
  };

  // Custom configuration
  custom?: Record<string, any>;
}

Theme Configuration

interface ThemeConfig extends BlogConfig {
  theme: ThemeName;
}

type ThemeComponent = React.FC<{
  config: ThemeConfig;
  children: React.ReactNode;
}>;

// Available themes
type ThemeName = "nova" | "atlas" | "pulse" | "prism" | "quantum" | "helix";

Development

Prerequisites

  • Node.js 18.0.0 or higher
  • TypeScript 5.3.0 or higher
  • React 18.0.0 or higher

Setup

# Clone the repository
git clone https://github.com/WritelyBlog/writely.git
cd writely/packages/@writely/core

# Install dependencies
pnpm install

# Build the package
pnpm build

# Run in development mode
pnpm dev

Development Workflow

  1. Install Dependencies: pnpm install
  2. Build Package: pnpm build
  3. Run Tests: pnpm test
  4. Lint Code: pnpm lint
  5. Watch Mode: pnpm dev

Scripts

  • pnpm build - Build the core package with TypeScript compilation
  • pnpm dev - Watch mode for development with hot reload
  • pnpm lint - Run ESLint with TypeScript support
  • pnpm clean - Clean build artifacts and temporary files
  • pnpm test - Run unit and integration tests
  • pnpm type-check - Run TypeScript type checking
  • pnpm format - Format code with Prettier
  • pnpm validate - Validate package configuration and dependencies
  • pnpm schema:generate - Generate JSON schemas from Zod schemas

Architecture

The core package is structured for modularity, type safety, and extensibility:

src/
├── index.ts              # Main exports and re-exports
├── schemas/              # Zod schemas for validation
│   ├── blog.ts          # Blog configuration and content schemas
│   └── generated/       # Generated schema files
├── themes/              # Theme components and layouts
│   ├── index.ts         # Theme exports and utilities
│   ├── nova/            # Nova theme implementation
│   │   └── layout.tsx   # Nova theme layout component
│   ├── atlas/           # Atlas theme implementation
│   ├── pulse/           # Pulse theme implementation
│   ├── prism/           # Prism theme implementation
│   ├── quantum/         # Quantum theme implementation
│   └── helix/           # Helix theme implementation
├── styles/              # Global styles and design system
│   └── globals.css      # Global CSS with design tokens
└── lib/                 # Utility functions
    └── utils.ts         # Shared utilities (cn function)

Core Components

Schema System: Comprehensive Zod schemas for runtime validation with TypeScript type generation.

Theme System: Modular theme architecture with consistent API and component structure.

Design System: CSS custom properties with dark mode support and responsive design tokens.

Utility Functions: Shared utilities for common operations like class name merging.

Type Safety: Full TypeScript support with generated types from Zod schemas.

Validation Engine: Runtime validation for all configuration and content with helpful error messages.

Theme Components: React components for each theme with consistent props and behavior patterns.

SEO Schemas: Comprehensive SEO meta tag schemas with Open Graph and Twitter Card support.

Contributing

  1. Fork Repository: Create a fork of the main repository
  2. Create Feature Branch: git checkout -b feature/new-schema
  3. Make Changes: Implement new functionality with proper TypeScript types
  4. Add Tests: Include unit tests for new schemas and utilities
  5. Update Documentation: Update README and API documentation
  6. Run Validation: Ensure all tests pass and code is properly formatted
  7. Submit Pull Request: Create detailed pull request with description

Development Guidelines

  • Follow TypeScript best practices with strict type checking
  • Implement comprehensive error handling with helpful error messages
  • Add unit tests for all new schemas and utilities
  • Maintain backward compatibility for existing schemas
  • Use consistent naming conventions for schemas and types
  • Follow the established code style and architecture patterns
  • Ensure all schemas have proper validation and error messages

License

MIT License - see LICENSE for details.