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

faceted-prompting

v0.2.1

Published

Faceted Prompting — structured prompt composition for LLMs

Readme

faceted-prompting

Faceted Prompting 解説記事

Structured prompt composition for LLMs — decompose prompts into reusable facets and compose them into LLM-ready messages.

faceted-prompting separates prompt concerns into distinct facets (persona, policy, knowledge, instruction), each with a defined role and message placement. This keeps prompts modular, testable, and maintainable as they grow in complexity.

Why Faceted Prompting

Separation of concerns — Each facet has a single responsibility. Persona defines who the agent is, policies define how it should behave, knowledge provides what it needs to know, and instructions define what to do. Changes to one facet don't affect others.

Deterministic placement — Persona always goes to the system prompt. Policies, knowledge, and instructions always go to the user message. This placement rule is enforced by the library, not left to convention.

Composable — Facets are plain Markdown files. Mix and match personas, policies, and knowledge across different workflows. Share them as repertoire packages via @owner/repo/facet-name scope references.

Framework-independent — Zero dependencies on any specific AI framework. Use it with Claude, OpenAI, or any LLM provider.

Facet Kinds

| Facet | Placement | Role | |-------|-----------|------| | Persona | System prompt | WHO — agent identity and character | | Policy | User message | HOW — rules, standards, constraints | | Knowledge | User message | WHAT TO KNOW — domain context, architecture | | Instruction | User message | WHAT TO DO — the specific task |

Install

npm install faceted-prompting

Global CLI:

npm install -g faceted-prompting
facet init
facet pull-sample

Quick Start

As a library

import { compose } from 'faceted-prompting';

const result = compose(
  {
    persona: { body: 'You are a senior TypeScript developer.' },
    policies: [{ body: 'Follow clean code principles. No any types.' }],
    knowledge: [{ body: 'The project uses Vitest for testing.' }],
    instruction: { body: 'Implement a retry function with exponential backoff.' },
  },
  { contextMaxChars: 8000 },
);

// result.systemPrompt → "You are a senior TypeScript developer."
// result.userMessage  → policies + knowledge + instruction (in order)

As a CLI

# Create local defaults under ~/.faceted
facet init

# Pull sample facets from TAKT on GitHub
facet pull-sample

# Compose prompts with auto-detected context
facet compose

# Install a skill to Claude Code or Codex
facet install skill

facet init creates ~/.faceted/ with config and empty directories. Run facet pull-sample to populate sample facets, compositions, and templates:

~/.faceted/
├── config.yaml
├── facets/
│   ├── persona/          # Persona Markdown files
│   ├── knowledge/        # Domain knowledge files
│   ├── policies/         # Policy/rules files
│   └── compositions/     # Compose definition YAML files
└── templates/            # Skill templates

CLI Commands

| Command | Description | |---------|-------------| | facet init | Create local config and empty facet directories | | facet pull-sample | Pull sample coding facets from TAKT on GitHub | | facet compose | Auto-detect context, compose prompts, and write to files | | facet install skill | Install a skill with facets to Claude Code or Codex |

See the CLI Reference for details.

Compose Definition

Place definition files in ~/.faceted/compositions/*.yaml:

name: release
description: Release summary composition
persona: coder
knowledge:
  - architecture
policies:
  - quality
instruction: Summarize release impact.
order:
  - knowledge
  - policies
  - instruction
  • name and persona are required.
  • order controls user-message section order (default: policiesknowledgeinstruction).
  • instruction can be a facet file reference or inline text.

Scope References

Reference facets from installed repertoire packages using @owner/repo/facet-name syntax:

persona: "@nrslib/takt-fullstack/expert-coder"
knowledge:
  - "@nrslib/takt-fullstack/architecture"

Scope references resolve to ~/.faceted/repertoire/@{owner}/{repo}/facets/{kind}/{name}.md.

API

compose(facets, options)

Core composition function. Takes a FacetSet and ComposeOptions, returns a ComposedPrompt with systemPrompt and userMessage.

composePromptPayload(params)

Higher-level API that composes prompts from a ComposeDefinition and also returns copyFiles metadata listing the source file paths used.

FileDataEngine

File-system backed facet loader. Reads {root}/{kind}/{key}.md.

import { FileDataEngine } from 'faceted-prompting';

const engine = new FileDataEngine('./prompts');
const persona = await engine.resolve('personas', 'coder');

CompositeDataEngine

Chains multiple DataEngine instances with first-match-wins resolution. Useful for layering project-level facets over global defaults.

import { FileDataEngine, CompositeDataEngine } from 'faceted-prompting';

const engine = new CompositeDataEngine([
  new FileDataEngine('./project/facets'),   // project-level (wins)
  new FileDataEngine('~/.faceted/facets'),   // global fallback
]);

renderTemplate(template, vars)

Minimal template engine with {{variable}} substitution and {{#if var}}...{{else}}...{{/if}} conditionals.

escapeTemplateChars(str)

Escapes curly braces to full-width Unicode equivalents to prevent template injection in user-supplied content.

See the API Reference for the full API surface.

Project Structure

~/.faceted/                     # Global config (created on first run)
├── config.yaml
├── facets/
│   ├── persona/
│   ├── knowledge/
│   ├── policies/
│   └── compositions/
├── templates/                  # Skill install templates
└── repertoire/                 # Installed repertoire packages

Documentation

| Document | Description | |----------|-------------| | Concepts | Faceted Prompting design methodology | | CLI Reference | All commands and options | | API Reference | Library API surface | | Changelog | Version history |

Contributing

See CONTRIBUTING.md for details.

License

MIT — See LICENSE for details.