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

m14i-blogging

v1.1.0

Published

Drag & drop blog builder with customizable layouts and content blocks for React and Next.js

Readme

m14i-blogging

A complete blog management system for React/Next.js applications with admin interface and public blog display.

npm version Storybook

Links

What is m14i-blogging?

A complete blog content management solution with two main components:

  • BlogAdmin - Complete admin interface for managing posts, categories, and tags
  • Blog - Public-facing blog with multiple layouts, search, and filtering

Quick Start

Installation

npm install m14i-blogging

# Install peer dependencies
npm install @hello-pangea/dnd react-markdown remark-gfm lucide-react

# Optional: For Supabase integration
npm install @supabase/supabase-js @supabase/ssr

1. Setup Database

Apply the blog schema migrations to your Supabase database:

supabase db push

Or copy migrations from node_modules/m14i-blogging/supabase/migrations/

Migrations included:

  • 20260405000000_create_blog_schema.sql — Blog posts, media, search
  • 20260405000001_add_taxonomy_tables.sql — Categories and tags

2. Configure Tailwind

Tailwind v4 — add to your app/globals.css:

@import "tailwindcss";
@source "../node_modules/m14i-blogging/dist";

Tailwind v3 — add to your tailwind.config.js:

module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './node_modules/m14i-blogging/dist/**/*.{js,mjs,cjs}', // Add this line
  ],
  // ... rest of config
}

3. Import Styles

In your root layout or _app.tsx:

import 'm14i-blogging/styles';

Using BlogAdmin

Complete admin interface for managing your blog.

Create API Routes

app/api/blog/route.ts

import { createClient } from "@/lib/supabase/server";
import { createListPostsHandler, createCreatePostHandler } from "m14i-blogging/server";
import { createBlogClient } from "m14i-blogging/client";

async function getBlogClient() {
  const supabase = await createClient();
  return createBlogClient(supabase);
}

export const GET = createListPostsHandler(getBlogClient);
export const POST = createCreatePostHandler(getBlogClient, checkAuth);

app/api/blog/[id]/route.ts

import { createClient } from "@/lib/supabase/server";
import { createUpdatePostHandler, createDeletePostHandler } from "m14i-blogging/server";
import { createBlogClient } from "m14i-blogging/client";

async function getBlogClient() {
  const supabase = await createClient();
  return createBlogClient(supabase);
}

export const PATCH = createUpdatePostHandler(getBlogClient, checkAuth);
export const DELETE = createDeletePostHandler(getBlogClient, checkAuth);

app/api/blog/categories/route.ts and app/api/blog/tags/route.ts - Similar pattern

Create Admin Page

app/admin/blog/page.tsx

import { BlogAdmin } from "m14i-blogging/admin";
import { Button, Input, Card, Badge } from "@/components/ui";
import { BlogBuilder } from "m14i-blogging";

export default async function BlogAdminPage() {
  const user = await getUser(); // Your auth logic
  const isAdmin = user?.role === "admin";

  return (
    <BlogAdmin
      isAllowed={isAdmin}
      currentUser={user}
      basePath="/admin/blog"
      apiBasePath="/api/blog"
      components={{
        Button,
        Input,
        Card,
        Badge,
        BlogBuilder,
      }}
    />
  );
}

Features:

  • ✅ Complete CRUD operations for posts, categories, and tags
  • ✅ Rich drag-and-drop editor (BlogBuilder)
  • ✅ Live preview system
  • ✅ Auto-save functionality
  • ✅ SEO metadata fields
  • ✅ Inline taxonomy creation
  • ✅ Access control
  • ✅ Fully customizable

📖 Complete BlogAdmin Guide →

Using Blog

Public-facing blog interface with multiple layouts and filtering.

Create Blog Page

app/blog/[[...path]]/page.tsx

import { Blog } from "m14i-blogging/public";
import { Button, Card, Badge, Input } from "@/components/ui";

export default function BlogPage() {
  return (
    <Blog
      basePath="/blog"
      apiBasePath="/api/blog"
      display={{
        layout: "grid", // "grid" | "list" | "masonry" | "magazine"
        postsPerPage: 9,
      }}
      features={{
        search: true,
        categoryFilter: true,
        tagFilter: true,
        relatedPosts: true,
      }}
      components={{
        Button,
        Card,
        Badge,
        Input,
      }}
    />
  );
}

Features:

  • ✅ Multiple layouts (Grid, List, Masonry, Magazine)
  • ✅ Internal routing (list/detail/category/tag/search)
  • ✅ Full-text search
  • ✅ Category and tag filtering
  • ✅ Pagination
  • ✅ Related posts
  • ✅ SEO-ready
  • ✅ Fully customizable

📖 Complete Blog Guide →

Customization

Quick Theme with CSS Variables

:root {
  --blog-primary: 220 100% 50%;
  --blog-font-family: 'Inter', sans-serif;
  --blog-radius-lg: 1rem;
}

Custom Styling with ClassName Props

<Blog
  classNames={{
    container: "max-w-6xl mx-auto px-8",
    postTitle: "text-5xl font-bold text-blue-600"
  }}
/>

📖 Complete Styling Guide →

SEO Features

Automatic SEO optimization included:

  • ✅ Meta tags generation (title, description, keywords)
  • ✅ Open Graph tags for social sharing
  • ✅ Twitter Card tags
  • ✅ JSON-LD structured data (Schema.org)
  • ✅ Reading time calculation
  • ✅ Auto-generated excerpts

📖 Complete SEO Guide →

Content Blocks

Supported content block types:

  • Text - Markdown-formatted text
  • Image - Images with captions and alt text
  • Video - YouTube and Vimeo embeds
  • Carousel - Interactive image slideshow
  • Quote - Styled blockquotes
  • PDF - Embed or download PDFs

Layout Options

Column Layouts

  • 1-column, 2-columns, 3-columns
  • 2-columns-wide-left, 2-columns-wide-right

Grid Layouts

  • grid-2x2 (4 cells)
  • grid-3x3 (9 cells)
  • grid-2x3 (6 cells)
  • grid-4-even (4 equal columns)

TypeScript Support

Fully typed with comprehensive type exports:

import type {
  // Core types
  LayoutSection,
  ContentBlock,

  // Database types
  BlogPostRow,
  BlogPostInsert,
  BlogPostUpdate,
  BlogCategory,
  BlogTag,
} from 'm14i-blogging';

// Component prop types from their respective entry points
import type { BlogAdminProps } from 'm14i-blogging/admin';
import type { BlogProps } from 'm14i-blogging/public';

Package Exports

Clean separation through multiple entry points:

import { BlogBuilder, BlogBuilderWithDefaults, BlogPreview } from 'm14i-blogging';  // Core components
import { BlogAdmin } from 'm14i-blogging/admin';                    // Admin interface
import { Blog } from 'm14i-blogging/public';                        // Public blog
import { createBlogClient } from 'm14i-blogging/client';            // Data layer
import { createListPostsHandler } from 'm14i-blogging/server';      // API handlers
import 'm14i-blogging/styles';                                      // Styles

Tip: BlogBuilderWithDefaults ships with built-in fallback UI components — no shadcn/ui required.

AI Content Generation

The package includes an AI-powered content generator using Anthropic's Claude API. The @anthropic-ai/sdk dependency is bundled with the package — no extra install needed.

Recommended Model

Claude Haiku 4.5 (claude-haiku-4-5) - Best choice for blog generation:

  • ⚡ Fast JSON generation (2x faster than Haiku 3.5)
  • 💰 Cost-effective (3x cheaper than Sonnet 4)
  • 🎯 Excellent coding performance (similar to Sonnet 4)
  • 📊 Consistent structured output with temperature 0.3

Example Configuration

import { createAIContentGenerator } from "m14i-blogging/server";

const generator = createAIContentGenerator({
  apiKey: process.env.ANTHROPIC_API_KEY,
  model: "claude-haiku-4-5", // Recommended
  maxTokens: 800,
  temperature: 0.3, // Lower for consistent JSON
});

// Generate layout
const layout = await generator.generateLayout({
  prompt: "Article about web development",
  language: "fr", // "en" | "fr"
});

Note: Claude Haiku 3.5 (claude-3-5-haiku-20241022) was retired on February 19, 2026.

Documentation

📚 Complete documentation:

Live Examples

Explore interactive examples in our Storybook:

View Storybook →

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT