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

@genzai/slots

v0.2.2

Published

Slot-based content preservation for code generation

Readme

@genzai/slots

Slot-based content preservation for code generation. Preserve user-written code across regeneration cycles.

Installation

npm install @genzai/slots @genzai/core
# or
pnpm add @genzai/slots @genzai/core
# or
yarn add @genzai/slots @genzai/core

Overview

@genzai/slots allows you to mark sections of generated code that should be preserved when files are regenerated. This is essential for code generators that need to support both generated and hand-written code in the same files.

Features

  • 📍 Slot Markers: Define preservable regions with JSDoc-style markers
  • 🔄 Content Preservation: Automatically restore slot content during regeneration
  • 🏷️ Metadata Support: Attach metadata to slots for advanced use cases
  • 🔌 Middleware Integration: Seamlessly integrates with @genzai/core

Quick Start

import { write } from "@genzai/core";
import { slot, slotMiddleware } from "@genzai/slots";

// In your template
const template = () => `
export class MyClass {
  ${slot.begin("custom-methods")}
  // Add your custom methods here
  ${slot.end}
}
`;

// Use the middleware when writing
await write(plan, "./output", [], {
  middlewares: [slotMiddleware],
});

Slot Syntax

Slots are defined using JSDoc-style comments:

/**
 * @slot custom-code - Content will be preserved across regeneration
 */
// Your custom code here
/** @end-slot */

Using the Helper

import { slot } from "@genzai/slots";

const code = `
class Example {
  ${slot.begin("methods")}
  // Custom methods go here
  ${slot.end}
}
`;

With Metadata

const code = `
${slot.begin("config", { version: 1, required: true })}
// Configuration code
${slot.end}
`;

API Reference

slot

Helper object for creating slot markers.

slot.begin(name, meta?)

Creates a begin marker for a slot.

  • name - Unique identifier for the slot
  • meta - Optional metadata object
slot.begin("custom-code");
slot.begin("config", { version: 1, editable: true });

slot.end

The end marker for a slot (constant string).

slot.end; // /** @end-slot */

extractSlots(fileContent)

Extracts all slots from file content.

import { extractSlots } from "@genzai/slots";

const content = `
/**
 * @slot test - Test slot
 * @version 1
 */
const custom = "code";
/** @end-slot */
`;

const slots = extractSlots(content);
// {
//   test: {
//     id: "test",
//     content: "\nconst custom = \"code\";\n",
//     meta: { version: 1 },
//     definitionStartLine: 2,
//     contentStartLine: 5,
//     contentEndLine: 7,
//     definitionEndLine: 7
//   }
// }

applySlots(generatedContent, savedSlots)

Applies saved slot contents to newly generated content.

import { applySlots, extractSlots } from "@genzai/slots";

// Extract slots from existing file
const existingContent = await fs.readFile("file.ts", "utf8");
const savedSlots = extractSlots(existingContent);

// Apply to new generated content
const newContent = generateContent();
const merged = applySlots(newContent, savedSlots);

slotMiddleware

Middleware that automatically extracts and applies slots during the write process.

import { write } from "@genzai/core";
import { slotMiddleware } from "@genzai/slots";

await write(plan, "./output", [], {
  middlewares: [slotMiddleware],
});

Types

Slot

type Slot = {
  id: string;
  content: string;
  meta: SlotMetaData;
  definitionStartLine: number;
  contentStartLine: number;
  contentEndLine: number;
  definitionEndLine: number;
};

SlotMetaData

type SlotMetaData = Record<string, string | number | boolean>;

How It Works

  1. First Generation: Slots are created with empty or default content
  2. User Edits: Users add their custom code inside slot markers
  3. Regeneration: The middleware extracts existing slot content
  4. Merging: Saved content is reinserted into newly generated slots
  5. Writing: Final merged content is written to disk

Example: React Component Generator

import { file } from "@genzai/core";
import { slot } from "@genzai/slots";

const componentGenerator = (name: string) => file(
  `${name}.tsx`,
  () => `
import React from 'react';

interface ${name}Props {
  ${slot.begin("props")}
  // Add your custom props here
  ${slot.end}
}

export const ${name}: React.FC<${name}Props> = (props) => {
  ${slot.begin("hooks")}
  // Add your custom hooks here
  ${slot.end}

  return (
    <div>
      ${slot.begin("jsx")}
      <p>Default content</p>
      ${slot.end}
    </div>
  );
};

${slot.begin("exports")}
// Add additional exports here
${slot.end}
`
);

After first generation, users can add their code:

export const Button: React.FC<ButtonProps> = (props) => {
  /**
   * @slot hooks - Custom hooks
   */
  const [count, setCount] = useState(0);
  const theme = useTheme();
  /** @end-slot */

  return (
    <div>
      {/* ... */}
    </div>
  );
};

On regeneration, the custom hooks are preserved!

Best Practices

  1. Unique Names: Use descriptive, unique slot names
  2. Documentation: Add comments in slot markers explaining their purpose
  3. Sensible Defaults: Provide helpful default content in slots
  4. Metadata: Use metadata to version slots or mark them as required
  5. Indentation: The middleware preserves original indentation

Related Packages

  • @genzai/core - Core generation framework (required)
  • @genzai/merge-strategy - File conflict resolution
  • @genzai/logging - Logging middleware

License

MIT