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

@leeforge/fusion-cli

v0.1.0

Published

CLI tool for Leeforge Fusion framework

Readme

Leeforge CLI ⚡

Command-line interface for Leeforge Fusion framework.

Version License Build

📚 Table of Contents


🎯 What is Leeforge CLI?

Leeforge CLI is a powerful command-line tool that helps you:

  • Initialize new Leeforge Fusion projects with templates
  • Develop with hot module replacement
  • Build optimized production bundles
  • Generate code scaffolding for pages, APIs, and components
  • Manage your project configuration

🚀 Installation

npm install -g @leeforge/fusion-cli

Or use with npx:

npx @leeforge/fusion-cli <command>

Binary Names:

  • leeforge-fusion (primary)
  • lf-fusion (alias)

Usage:

# Using primary binary
leeforge-fusion dev

# Using alias
lf-fusion dev

📖 Usage Guide

Leeforge CLI provides a comprehensive set of commands to streamline your development workflow.

1. Initialize Project

Create a new Leeforge Fusion project with a template:

# Create a new project with the basic template
leeforge init my-app

# Create a project with a specific template
leeforge init my-blog --template blog
leeforge init my-dashboard --template dashboard

# Available templates:
# - basic: Simple app with home and about pages
# - blog: Blog with posts, categories, and RSS
# - dashboard: Admin dashboard with authentication

Template Comparison:

| Template | Features | Best For | | ------------- | ------------------------------------ | --------------------- | | basic | Home page, About page, Basic routing | Learning, Simple apps | | blog | Posts, Categories, RSS feed, Search | Content websites | | dashboard | Authentication, Admin panel, Charts | Business applications |

2. Development Server

Start the development server with hot module replacement:

# Start on default port (3000)
leeforge dev

# Start on custom port
leeforge dev --port 3001

# Start with host binding
leeforge dev --host 0.0.0.0

# Start with custom config
leeforge dev --config ./custom.config.ts

Features:

  • ✅ Hot Module Replacement (HMR)
  • ✅ Fast refresh
  • ✅ Error overlay
  • ✅ TypeScript support
  • ✅ Automatic routing

3. Build for Production

Create an optimized production build:

# Standard build
leeforge build

# Build with custom output directory
leeforge build --outDir dist

# Build with source maps
leeforge build --sourcemap

# Build for specific environment
leeforge build --mode production

Build Output:

  • Optimized JavaScript bundles
  • Static HTML files
  • CSS extraction
  • Asset optimization
  • Type definitions

4. Code Generation

Generate code scaffolding to speed up development:

# Generate a page
leeforge generate page blog/[id]

# Generate an API route
leeforge generate api users/[id]

# Generate a component
leeforge generate component Button

# Generate middleware
leeforge generate middleware auth

# Preview without creating files
leeforge generate page about --dry-run

# Force overwrite existing files
leeforge generate page blog --force

📋 Available Commands

init

Initialize a new Leeforge Fusion project.

Syntax:

leeforge-fusion init [name] [options]

Arguments:

  • name: Project name (default: "my-app")

Options:

  • -t, --template <type>: Template to use (basic, blog, dashboard) (default: "basic")

Available Templates:

  • basic: Simple app with home and about pages
  • blog: Blog with posts, categories, and RSS
  • dashboard: Admin dashboard with authentication

Examples:

# Basic project (default template)
leeforge-fusion init
leeforge-fusion init my-app

# Blog template
leeforge-fusion init my-blog --template blog

# Dashboard template
leeforge-fusion init my-dashboard --template dashboard

Options:

  • --template <name>: Use a specific template (basic, blog, dashboard)
  • --git: Initialize git repository
  • --install: Install dependencies automatically
  • --pm <manager>: Package manager (npm, yarn, pnpm)

Examples:

# Basic project
leeforge init my-app

# Blog with git and install
leeforge init my-blog --template blog --git --install

# Dashboard with pnpm
leeforge init my-dashboard --template dashboard --pm pnpm

dev

Start the development server.

Syntax:

leeforge-fusion dev [options]

Options:

  • -p, --port <number>: Port number (default: 3000, or from config)

Features:

  • ✅ Hot Module Replacement (HMR)
  • ✅ Automatic app directory detection
  • ✅ Config file support
  • ✅ TypeScript support

Examples:

# Default development (port 3000)
leeforge-fusion dev

# Custom port
leeforge-fusion dev --port 3001
leeforge-fusion dev -p 3001

How it works:

  1. Loads leeforge.config.ts from project root
  2. Detects app directory (src/app, app, src, or current directory)
  3. Starts Vite dev server with HMR
  4. Serves your Leeforge Fusion application

Options:

  • --port <number>: Port number (default: 3000)
  • --host <address>: Host address (default: localhost)
  • --config <path>: Custom config file path
  • --open: Open browser automatically
  • --https: Use HTTPS with self-signed certificate

Examples:

# Default development
leeforge dev

# Custom port and open browser
leeforge dev --port 3001 --open

# With HTTPS
leeforge dev --https

build

Build the application for production.

Syntax:

leeforge-fusion build

Options:

  • None (uses configuration from leeforge.config.ts)

Features:

  • ✅ Client-side bundle (dist/client)
  • ✅ Server-side bundle (dist/server)
  • ✅ Code splitting (vendor chunks)
  • ✅ Automatic optimization

Examples:

# Standard production build
leeforge-fusion build

Build Output:

dist/
├── client/           # Client-side bundles
│   ├── index.js
│   ├── vendor.js     # SolidJS, TanStack libraries
│   └── assets/
└── server/           # Server-side bundle
    └── entry-server.js

How it works:

  1. Loads leeforge.config.ts from project root
  2. Builds client-side bundle with code splitting
  3. Builds server-side bundle for SSR
  4. Outputs to dist/ directory

Options:

  • --outDir <path>: Output directory (default: dist)
  • --sourcemap: Generate source maps
  • --mode <mode>: Build mode (production, development)
  • --analyze: Analyze bundle size
  • --minify: Minify output

Examples:

# Standard production build
leeforge build

# With source maps and analysis
leeforge build --sourcemap --analyze

# Custom output directory
leeforge build --outDir ./build

generate (alias: g)

Generate code scaffolding.

Syntax:

leeforge-fusion generate <type> <name> [options]
leeforge-fusion g <type> <name> [options]

Arguments:

  • type: Type to generate (page, api, component)
  • name: Name of the item (e.g., "blog/[id]", "users/[id]", "Button")

Options:

  • --dry-run: Show what would be generated without creating files

Supported Types:

  • page: Generate a page component
  • api: Generate an API route
  • component: Generate a component

Examples:

# Generate page
leeforge-fusion generate page blog/[id]

# Generate API route
leeforge-fusion generate api users/[id]

# Generate component
leeforge-fusion generate component Button

# Preview without creating files
leeforge-fusion generate page about --dry-run

# Using alias
leeforge-fusion g page contact

Types:

  • page: Generate a page component
  • api: Generate an API route
  • component: Generate a component
  • middleware: Generate middleware
  • layout: Generate a layout component

Options:

  • --dry-run: Preview without creating files
  • --force: Overwrite existing files
  • --typescript: Generate TypeScript files
  • --css: Include CSS module
  • --test: Include test file

Examples:

# Generate page with params
leeforge generate page blog/[id]

# Generate API with multiple methods
leeforge generate api users/[id]

# Generate component with tests
leeforge generate component Button --test --css

# Preview generation
leeforge generate page about --dry-run

🎯 Generated Code Examples

Page

Command:

leeforge-fusion generate page blog/[id]

Generated Files:

app/blog/[id]/
└── index.tsx          # Main page component

Generated Code:

// app/blog/[id]/index.tsx
import { createSignal } from "solid-js";
import { createServerData } from "@leeforge/fusion/data";

export default function Page() {
  const [count, setCount] = createSignal(0);
  const data = createServerData(async ({ params, queryClient }) => {
    return { message: "Hello from blog/[id]" };
  });

  return (
    <div>
      <h1>blog/[id]</h1>
      <p>Count: {count()}</p>
      <button onClick={() => setCount(c => c + 1)}>Increment</button>
      <p>Data: {data()?.message}</p>
    </div>
  );
}

export const loader = async ({ queryClient, params }) => {
  return { message: "Hello from blog/[id]" };
};

export const guards = [];

Features:

  • ✅ Server-side data loading with createServerData
  • ✅ Client-side state with createSignal
  • ✅ Type-safe route parameters
  • ✅ Loader function for data fetching
  • ✅ Guards array for route protection
  • ✅ Interactive counter example

API Route

Command:

leeforge-fusion generate api users/[id]

Generated Files:

app/api/users/[id]/
└── route.ts           # API route handler

Generated Code:

// app/api/users/[id]/route.ts
export async function GET({ request, params }) {
  return Response.json({ message: "GET users/[id]" });
}

export async function POST({ request, params }) {
  const body = await request.json();
  return Response.json({ message: "POST users/[id]", data: body });
}

Features:

  • ✅ Multiple HTTP methods (GET, POST)
  • ✅ Request and params access
  • ✅ JSON response handling
  • ✅ Request body parsing
  • ✅ Type-safe parameters

Component

Command:

leeforge-fusion generate component Button

Generated Files:

components/Button/
└── Button.tsx         # Main component

Generated Code:

// components/Button/Button.tsx
import { createSignal } from "solid-js";

export interface ButtonProps {
  label?: string;
}

export default function Button(props: ButtonProps) {
  const [count, setCount] = createSignal(0);

  return (
    <div class="component">
      <h3>{props.label || "Button"}</h3>
      <p>Count: {count()}</p>
      <button onClick={() => setCount(c => c + 1)}>Click me</button>
    </div>
  );
}

Features:

  • ✅ TypeScript interface
  • ✅ Props with default values
  • ✅ Client-side state management
  • ✅ Interactive counter example
  • ✅ Simple and reusable

Middleware

Command:

leeforge generate middleware auth

Generated Files:

src/middleware/
├── auth.ts            # Middleware logic
└── types.ts           # Type definitions

Generated Code:

// src/middleware/auth.ts
import { createMiddleware } from "leeforge-fusion/middleware";
import { redirect } from "leeforge-fusion/middleware/redirect";

export const requireAuth = createMiddleware(async (ctx, next) => {
  // Check authentication
  const session = await getSession(ctx);

  if (!session.user) {
    throw redirect("/login");
  }

  // Attach user to context
  ctx.user = session.user;

  await next();
});

export const requireAdmin = createMiddleware(async (ctx, next) => {
  // Check admin role
  if (!ctx.user || ctx.user.role !== "admin") {
    throw redirect("/unauthorized");
  }

  await next();
});

Features:

  • ✅ Authentication checks
  • ✅ Role-based access control
  • ✅ Context modification
  • ✅ Redirect handling
  • ✅ Type safety

📁 Project Structure

After running leeforge-fusion init, your project will have:

my-app/
├── src/
│   ├── app/
│   │   ├── layout.tsx          # Root layout
│   │   ├── index.tsx           # Home page
│   │   ├── about.tsx           # About page
│   │   └── blog/
│   │       ├── index.tsx       # Blog list
│   │       └── [id].tsx        # Dynamic blog post
│   └── middleware/
│       └── auth.ts             # Authentication middleware
├── leeforge.config.ts          # Configuration
├── package.json
└── tsconfig.json

After running leeforge-fusion generate, your project will have:

my-app/
├── app/
│   ├── blog/[id]/
│   │   └── index.tsx           # Generated page
│   └── api/users/[id]/
│       └── route.ts            # Generated API
├── components/
│   └── Button/
│       └── Button.tsx          # Generated component
└── ...

🔧 Configuration

The CLI automatically creates leeforge.config.ts in your project root:

import { defineConfig } from "@leeforge/fusion";

export default defineConfig({
  api: {
    prefix: "/api",
  },
  vite: {
    server: {
      port: 3000,
    },
  },
});

Configuration Options

API Configuration:

  • prefix: API route prefix (default: "/api")
  • timeout: Request timeout in milliseconds

Vite Configuration:

  • server.port: Development server port (default: 3000)
  • server.host: Host address
  • build.outDir: Build output directory
  • build.sourcemap: Generate source maps
  • Any Vite configuration option is supported

Route Guards:

  • guards: Object mapping routes to middleware files
  • Example: "/admin/*": "./src/middleware/auth.ts"

How Configuration Works

  1. Loading: CLI loads leeforge.config.ts from project root
  2. Merging: Configuration is merged with framework defaults
  3. Usage: Used by dev and build commands
  4. Optional: If no config exists, defaults are used

🛠️ Development

Local Development

# Clone the repository
git clone https://github.com/JsonLee12138/leeforge-fusion.git
cd leeforge-fusion

# Install dependencies
pnpm install

# Build CLI
cd packages/cli
pnpm run build

# Test CLI locally
./dist/index.js dev --port 3000

Testing the CLI

# Run tests
pnpm test

# Type check
pnpm run typecheck

# Test specific commands
./dist/index.js init test-app --template basic
./dist/index.js generate page test-page --dry-run

Build Commands

# Build the CLI
pnpm run build

# Build with watch mode
pnpm run dev

Code Quality

# Type check
pnpm run typecheck

📦 Publishing

Prepare for Publishing

# Build the CLI
pnpm run build

# Run tests
pnpm test

# Check type safety
pnpm run typecheck

Publish to npm

# Login to npm (if not already)
npm login

# Publish public package
npm publish --access public

# Publish with tag
npm publish --tag beta

Version Management

# Bump version
npm version patch  # 0.1.0 -> 0.1.1
npm version minor  # 0.1.0 -> 0.2.0
npm version major  # 0.1.0 -> 1.0.0

# Publish with version bump
npm version patch && npm publish --access public

🎯 CLI Architecture

Command Structure

leeforge-fusion
├── init [name] [options]
│   └── -t, --template <type>
├── dev [options]
│   └── -p, --port <number>
├── build
└── generate <type> <name> [options]
    └── --dry-run

Core Modules

Source Structure:

src/
├── index.ts              # CLI entry point
├── commands/
│   ├── init.ts           # Project initialization
│   ├── dev.ts            # Development server
│   ├── build.ts          # Production build
│   └── generate.ts       # Code generation
├── generators/
│   ├── page.ts           # Page generator
│   ├── api.ts            # API generator
│   └── component.ts      # Component generator
└── types.d.ts            # Type definitions

Command Implementation

init Command:

  • Loads templates from inline code (not external files)
  • Creates directory structure
  • Writes template files
  • Supports 3 templates: basic, blog, dashboard

dev Command:

  • Imports @leeforge/fusion dynamically
  • Loads configuration from leeforge.config.ts
  • Detects app directory automatically
  • Starts Vite dev server

build Command:

  • Uses Vite's build API
  • Builds client and server bundles
  • Code splitting for vendor chunks
  • Outputs to dist/ directory

generate Command:

  • Dynamic import of generators
  • Supports: page, api, component
  • Creates files in appropriate directories
  • Supports dry-run mode

Template System

Templates are defined inline in commands/init.ts:

const templates = {
  basic: {
    /* basic template files */
  },
  blog: {
    /* blog template files */
  },
  dashboard: {
    /* dashboard template files */
  },
};

Template Files Include:

  • src/app/layout.tsx
  • src/app/index.tsx
  • src/app/about.tsx (basic)
  • leeforge.config.ts
  • package.json
  • tsconfig.json

📊 CLI Features

Dynamic Imports

Commands are loaded dynamically to improve startup time:

// Only loads when command is executed
const { devCommand } = await import("./commands/dev");

Dry Run Mode

Preview code generation without creating files:

leeforge-fusion generate page blog/[id] --dry-run
# Shows what files would be created

Automatic Directory Detection

The dev command automatically detects your app directory:

Search Order:

  1. src/app
  2. app
  3. src
  4. Current directory

Detection Logic:

  • Looks for index.tsx, index.ts, page.tsx, page.ts, layout.tsx, or layout.ts
  • Uses the first directory with page files found

Help System

Get help for any command:

leeforge-fusion --help
leeforge-fusion init --help
leeforge-fusion generate --help

Error Handling

  • ✅ Graceful error messages
  • ✅ Process exit codes
  • ✅ Helpful suggestions
  • ✅ File existence checks

🚀 Performance

Startup Performance

  • Dynamic Imports: Commands loaded on-demand
  • Fast Startup: <100ms CLI startup time
  • Lazy Loading: Only loads required modules

Command Performance

  • Init: ~2-3 seconds to create project
  • Dev: Instant startup, HMR <100ms
  • Build: ~2-3 seconds for small apps
  • Generate: <50ms per generated file

Optimization Features

  • Code Splitting: Vendor chunks in build
  • Tree Shaking: Unused code elimination
  • Dynamic Imports: On-demand module loading
  • Fast Refresh: Vite HMR integration

🔍 Troubleshooting

Common Issues

Issue: Command not found

# Solution: Install globally or use npx
npm install -g @leeforge/fusion-cli
# or
npx @leeforge/fusion-cli <command>

Issue: Port already in use

# Solution: Use different port
leeforge-fusion dev --port 3001

Issue: Template not found

# Solution: Check available templates
leeforge-fusion init --help
# or use default template
leeforge-fusion init my-app

Issue: Generation fails

# Solution: Use dry-run to debug
leeforge-fusion generate page test --dry-run

Issue: Dev server won't start

# Solution: Check if leeforge.config.ts exists
# Create one if missing:
cat > leeforge.config.ts << 'EOF'
import { defineConfig } from "@leeforge/fusion";

export default defineConfig({
  api: {
    prefix: "/api",
  },
  vite: {
    server: {
      port: 3000,
    },
  },
});
EOF

Issue: Build fails

# Solution: Ensure src/app directory exists with page files
# Check structure:
ls -la src/app/
# Should have: layout.tsx, index.tsx, or page.tsx

🤝 Contributing

We welcome contributions! Please see the main repository for contribution guidelines.

📄 License

MIT License - see LICENSE for details.


Ready to build? Run leeforge init my-app to get started!