{"id":49875553,"url":"https://github.com/knid/composr","last_synced_at":"2026-05-15T12:10:28.967Z","repository":{"id":348109273,"uuid":"1196469038","full_name":"knid/composr","owner":"knid","description":"The prompt compiler for AI-first teams. Compose, version, test, and score your prompt systems — without code deploys.","archived":false,"fork":false,"pushed_at":"2026-03-30T20:15:17.000Z","size":322,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-30T21:29:07.536Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-30T18:21:20.000Z","updated_at":"2026-03-30T20:15:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/knid/composr","commit_stats":null,"previous_names":["knid/composr"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/knid/composr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knid%2Fcomposr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knid%2Fcomposr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knid%2Fcomposr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knid%2Fcomposr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knid","download_url":"https://codeload.github.com/knid/composr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knid%2Fcomposr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33066233,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-15T12:10:28.282Z","updated_at":"2026-05-15T12:10:28.960Z","avatar_url":"https://github.com/knid.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/placeholder-logo\" alt=\"Composr\" width=\"80\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eComposr\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eThe prompt compiler for AI-first teams.\u003c/strong\u003e\u003cbr /\u003e\n  Compose, version, test, and score your prompt systems — without code deploys.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://composr.dev/docs\"\u003eDocs\u003c/a\u003e \u0026middot;\n  \u003ca href=\"https://composr.dev/docs/quickstart\"\u003eQuickstart\u003c/a\u003e \u0026middot;\n  \u003ca href=\"https://app.composr.dev\"\u003eDashboard\u003c/a\u003e \u0026middot;\n  \u003ca href=\"https://composr.dev/discord\"\u003eDiscord\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@composr/sdk\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@composr/sdk?style=flat-square\u0026color=7c3aed\u0026label=npm\" alt=\"npm\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/composr/sdk-go\"\u003e\u003cimg src=\"https://img.shields.io/badge/go-pkg.go.dev-7c3aed?style=flat-square\" alt=\"Go\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/composr/composr/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-7c3aed?style=flat-square\" alt=\"License\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://composr.dev/discord\"\u003e\u003cimg src=\"https://img.shields.io/badge/discord-join-7c3aed?style=flat-square\u0026logo=discord\u0026logoColor=white\" alt=\"Discord\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/placeholder-screenshot\" alt=\"Composr Editor\" width=\"800\" /\u003e\n\u003c/p\u003e\n\n---\n\nExisting tools treat prompts as flat documents with variable slots. **Real prompt systems are programs** — with shared blocks, conditional branches, A/B variants, and multi-step pipelines.\n\nComposr is the first tool to treat them that way. Think **n8n for prompts** — a visual flow editor where blocks are nodes, conditions are IF gates, and experiments are percentage splits. Your SDK assembles prompts locally in \u003c1ms from synced configs. No deploys to change a prompt. Ever.\n\n\u003cbr /\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"50%\" valign=\"top\"\u003e\n\n\u003ch3\u003eI use AI in production\u003c/h3\u003e\n\nStop hardcoding prompts in Go constants, Python strings, and config files. Move them to Composr and get versioning, A/B testing, and scoring for free.\n\n**[Jump to quickstart](#quickstart)**\n\n\u003c/td\u003e\n\u003ctd width=\"50%\" valign=\"top\"\u003e\n\n\u003ch3\u003eI'm exploring\u003c/h3\u003e\n\nSee why teams at AI-first companies are switching from flat prompt management to composable prompt programs.\n\n**[Jump to how it works](#how-it-works)**\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## Why Composr?\n\nEvery AI company hits the same wall. You start with a few prompts hardcoded in your backend. Then you need variants for different contexts. Then conditional blocks. Then A/B testing. Suddenly you're managing a complex prompt program in raw code — and every change requires a PR, review, deploy, and pray.\n\n| Pain | Before Composr | With Composr |\n|------|-------------------|----------------|\n| Changing a prompt | Code PR \u0026rarr; review \u0026rarr; deploy \u0026rarr; 30 min | Edit in UI \u0026rarr; publish \u0026rarr; 2 seconds |\n| Testing variants | Manual, no data | A/B split with statistical significance |\n| Scoring quality | Guessing | LLM-as-judge auto-eval on every output |\n| Conditional logic | Hardcoded if/else chains | Visual IF nodes, drag and connect |\n| Multi-project types | Copy-paste with divergence | Shared blocks, composed per context |\n| Rollback | Git revert and redeploy | One click |\n\n---\n\n## Features\n\n| | Feature | Description |\n|---|---|---|\n| **Visual Flow Editor** | n8n-style canvas where blocks are nodes and conditions are IF gates. Drag, connect, compose. React Flow powered. |\n| **8 Node Types** | Start, Output, Block, IF Boolean, IF Switch, IF Percentage (A/B), IF Expression, Merge |\n| **Composable Blocks** | Reusable prompt fragments with version history. Share across compositions. |\n| **Conditional Assembly** | Route on any parameter — context vars, user ID, country, time of day, custom expressions. |\n| **A/B Testing** | Percentage IF nodes split traffic deterministically. Welch's t-test for statistical significance. |\n| **Auto-Scoring** | LLM-as-judge evaluates outputs automatically. 3 built-in scorers + custom. |\n| **SDK (TypeScript + Go)** | Syncs config, assembles locally in \u003c1ms. Zero network calls on the hot path. |\n| **Live Preview** | See the assembled prompt for any context — updates as you edit the flow. |\n| **Environments** | dev \u0026rarr; staging \u0026rarr; prod with one-click promotion and instant rollback. |\n| **Real-time Push** | SSE stream pushes config changes to connected SDKs instantly. |\n| **Audit Log** | Every mutation tracked — who changed what, when. |\n| **Rate Limiting** | Built-in sliding window protection for SDK endpoints. |\n\n---\n\n## Quickstart\n\n### 1. Install the SDK\n\n```bash\nnpm install @composr/sdk\n```\n\n```bash\ngo get github.com/composr/sdk-go\n```\n\n### 2. Three lines to assemble a prompt\n\n**TypeScript:**\n\n```typescript\nimport { Composr } from '@composr/sdk'\n\nconst pk = new Composr({ apiKey: 'pk_live_...', environment: 'prod' })\n\nconst result = await pk.compose('builder', {\n  projectType: 'ecommerce',\n  hasAuth: true,\n  outputMode: 'chat',\n})\n\nconsole.log(result.text)       // fully assembled prompt\nconsole.log(result.tokenCount) // 14200\nconsole.log(result.blocks)     // [\"role\", \"design-philosophy\", \"framework-rules\", ...]\n```\n\n**Go:**\n\n```go\npk := composr.New(composr.Config{\n    APIKey:      \"pk_live_...\",\n    Environment: \"prod\",\n})\ndefer pk.Close()\n\nresult, _ := pk.Compose(\"builder\", composr.ComposeContext{\n    \"projectType\": \"ecommerce\",\n    \"hasAuth\":     true,\n    \"outputMode\":  \"chat\",\n})\n\nfmt.Println(result.Text)       // fully assembled prompt\nfmt.Println(result.TokenCount) // 14200\n```\n\n### 3. Track outputs for auto-scoring\n\n```typescript\n// After your LLM responds:\nawait pk.track(result.id, {\n  input: userPrompt,\n  output: llmResponse,\n  model: 'claude-sonnet-4.6',\n  latencyMs: 3200,\n})\n// Platform auto-scores quality, relevance, instruction-following\n```\n\nThat's it. Your prompts are now managed, versioned, scored, and A/B testable.\n\n---\n\n## How It Works\n\n```\nYour application\n       |\n       v\n   Composr SDK (local, \u003c1ms)\n       |\n       |── 1. Syncs config on startup (REST + SSE for live updates)\n       |── 2. Caches compositions + blocks in memory\n       |── 3. On compose(): walks the flow graph locally\n       |      |\n       |      |── Block nodes → append prompt text\n       |      |── IF Boolean → evaluate context field, take true/false branch\n       |      |── IF Switch → match context value, take matching branch\n       |      |── IF Percentage → deterministic hash, select A/B variant\n       |      |── IF Expression → evaluate custom expression\n       |      |── Merge → rejoin branches\n       |      |\n       |      └── Returns assembled text + metadata (version, variant, tokens)\n       |\n       └── 4. track() sends LLM output for auto-scoring (async, non-blocking)\n```\n\n**Zero network calls** on the hot path. The SDK assembles prompts locally from cached config. Config syncs in the background via SSE — when you publish a change in the dashboard, connected SDKs pick it up within seconds.\n\n---\n\n## The Editor\n\nThe composition editor is the core product experience. It's a React Flow canvas with three areas:\n\n**Canvas** (center) — Drag nodes from the palette, connect them, configure IF conditions. Zoomable, pannable, with minimap.\n\n**Block Editor** (right panel) — Monaco editor for block content. Syntax highlighting, token count, version history.\n\n**Preview** (bottom) — Live assembled prompt for test context. Toggle context values and see which blocks are included/excluded in real time.\n\n### Node Types\n\n| Node | Visual | Purpose |\n|------|--------|---------|\n| **Start** | Green circle | Entry point, receives context |\n| **Block** | Green rectangle | Appends a prompt fragment |\n| **IF Boolean** | Purple \"IF\" | True/false branch on a context field |\n| **IF Switch** | Purple \"SW\" | Multi-branch on enum value (like `projectType`) |\n| **IF Percentage** | Purple \"%%\" | A/B split with deterministic user hashing |\n| **IF Expression** | Purple \"EX\" | Custom expression (`_time.hour \u003e= 18 \u0026\u0026 _req.country == \"TR\"`) |\n| **Merge** | Purple pill | Rejoins branches |\n| **Output** | Red circle | Returns assembled text |\n\n### IF Parameters\n\nEvery IF node can evaluate against:\n\n| Source | Examples | How |\n|--------|----------|-----|\n| **Context vars** | `projectType`, `hasAuth`, `userTier` | Passed by SDK at compose time |\n| **Request metadata** | `_req.ip`, `_req.country`, `_req.userId` | Auto-captured by SDK |\n| **Time** | `_time.hour`, `_time.dayOfWeek` | Evaluated at assembly time |\n| **Environment** | `_env.name` | dev / staging / prod |\n| **Custom expressions** | `_time.hour \u003e= 18 \u0026\u0026 _req.country == \"TR\"` | Full expression support |\n\n---\n\n## Scoring\n\nThree layers, from zero-effort to custom:\n\n### Layer 1: Automatic (always on)\n\nAssembly success, token efficiency, latency, response status — tracked on every call for free.\n\n### Layer 2: Auto-Eval (opt-in)\n\nLLM-as-judge scores a sample of outputs automatically:\n\n| Scorer | What it measures |\n|--------|-----------------|\n| Instruction Following | Does the output follow the prompt? |\n| Output Quality | Coherence, completeness, professionalism |\n| Relevance | Is the output relevant to the input? |\n\nEnable per composition. Configure sample rate (default 20%). Uses your judge model of choice.\n\n### Layer 3: Custom Scorers\n\nDefine your own evaluation criteria — JS functions or custom judge prompts.\n\n---\n\n## A/B Testing\n\nExperiments are built into the flow — not a separate system.\n\n1. Add a **Percentage IF node**: `50% → v2, 50% → v1`\n2. SDK assigns users deterministically (same user always sees same variant)\n3. Scores flow in via `pk.track()` — auto-eval runs automatically\n4. Dashboard shows winner with **statistical significance** (Welch's t-test)\n5. Promote the winner with one click\n\nNo experiment setup. No SDK changes. Just add a node and connect it.\n\n---\n\n## Self-Hosting\n\nComposr is open source. Deploy it anywhere:\n\n```bash\ngit clone https://github.com/composr/composr\ncd composr\ncp .env.example .env.local\n# Edit .env.local with your Clerk + Neon credentials\nnpm install\nnpx drizzle-kit push\nnpm run dev\n```\n\nOr deploy to Vercel in one click:\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/composr/composr)\n\n---\n\n## Architecture\n\n```\ncomposr/\n├── app/                    # Next.js 16 App Router\n│   ├── (app)/              # Authenticated pages (dashboard, editor, etc.)\n│   └── api/                # REST API (blocks, compositions, SDK endpoints)\n├── components/\n│   ├── editor/             # React Flow canvas + node components\n│   ├── layout/             # Sidebar, header\n│   └── ui/                 # shadcn/ui primitives\n├── lib/\n│   ├── schema.ts           # Drizzle ORM (PostgreSQL)\n│   ├── graph-engine.ts     # Flow graph → assembled text\n│   ├── expression-parser.ts # Safe expression evaluator\n│   ├── statistics.ts       # Welch's t-test for experiments\n│   └── eval-runner.ts      # LLM-as-judge scorer\n├── sdk/                    # TypeScript SDK (@composr/sdk)\n└── sdk-go/                 # Go SDK (github.com/composr/sdk-go)\n```\n\n**Tech stack:** Next.js 16 \u0026middot; TypeScript \u0026middot; Tailwind CSS \u0026middot; shadcn/ui \u0026middot; React Flow \u0026middot; Drizzle ORM \u0026middot; Neon Postgres \u0026middot; Clerk\n\n---\n\n## SDK Reference\n\n### TypeScript\n\n```bash\nnpm install @composr/sdk\n```\n\n| Method | Description |\n|--------|-------------|\n| `new Composr(config)` | Initialize with API key and environment |\n| `pk.compose(name, context)` | Assemble a prompt locally (\u003c1ms) |\n| `pk.track(id, payload)` | Send LLM output for auto-scoring |\n| `pk.score(id, metrics)` | Send manual metrics |\n| `pk.destroy()` | Stop background sync |\n\n### Go\n\n```bash\ngo get github.com/composr/sdk-go\n```\n\n| Method | Description |\n|--------|-------------|\n| `composr.New(config)` | Create client |\n| `pk.Compose(name, ctx)` | Assemble a prompt locally (\u003c1ms) |\n| `pk.Track(id, payload)` | Send LLM output for auto-scoring |\n| `pk.Score(id, metrics)` | Send manual metrics |\n| `pk.Close()` | Stop background sync |\n\n### REST API\n\n```bash\n# Compose\ncurl -X POST https://app.composr.dev/api/sdk/config/prod \\\n  -H \"Authorization: Bearer pk_live_...\"\n\n# Track\ncurl -X POST https://app.composr.dev/api/sdk/track \\\n  -H \"Authorization: Bearer pk_live_...\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"assemblyId\":\"asm_...\",\"input\":\"...\",\"output\":\"...\",\"model\":\"claude-sonnet-4.6\"}'\n```\n\n---\n\n## Comparison\n\n| | Composr | Langfuse | Braintrust | Humanloop |\n|---|---|---|---|---|\n| Composable blocks | Yes | No | No | No |\n| Visual flow editor | Yes (React Flow) | No | No | No |\n| Conditional IF nodes | Yes (4 types) | No | No | No |\n| A/B testing | Built into flow | Prompt labels | Experiments | Experiments |\n| Auto-scoring | LLM-as-judge | LLM-as-judge | AutoEvals | Model evals |\n| Local assembly (\u003c1ms) | Yes | No (API call) | No (API call) | No (API call) |\n| Real-time push (SSE) | Yes | No | No | No |\n| Go SDK | Yes | No | No | No |\n| Open source | Yes (MIT) | Yes (MIT) | No | No |\n| Self-hostable | Yes | Yes | No | No |\n\n**Composr treats prompts as programs. Everyone else treats them as documents.**\n\n---\n\n## Contributing\n\nWe love contributions. Check out the [Contributing Guide](CONTRIBUTING.md) for setup instructions and guidelines.\n\n```bash\ngit clone https://github.com/composr/composr\ncd composr\nnpm install\ncp .env.example .env.local\nnpm run dev\n```\n\n---\n\n## Community\n\n- [Discord](https://composr.dev/discord) — Chat with the team and other users\n- [GitHub Discussions](https://github.com/composr/composr/discussions) — Questions and feature requests\n- [Twitter / X](https://twitter.com/composrdev) — Updates and announcements\n\n---\n\n## License\n\nMIT. See [LICENSE](LICENSE) for details.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eStop deploying to change a prompt.\u003c/strong\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknid%2Fcomposr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknid%2Fcomposr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknid%2Fcomposr/lists"}