{"id":50736588,"url":"https://github.com/jg-wright/targetd","last_synced_at":"2026-06-10T14:02:27.238Z","repository":{"id":37797358,"uuid":"389720459","full_name":"jg-wright/targetd","owner":"jg-wright","description":"A speedy, extensible, typed, in-memory data store built in Typescript.","archived":false,"fork":false,"pushed_at":"2026-06-01T14:15:17.000Z","size":985264,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-06-01T16:13:45.943Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/jg-wright.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":null,"dco":null,"cla":null}},"created_at":"2021-07-26T17:45:36.000Z","updated_at":"2026-06-01T14:42:37.000Z","dependencies_parsed_at":"2026-01-06T17:09:17.539Z","dependency_job_id":null,"html_url":"https://github.com/jg-wright/targetd","commit_stats":null,"previous_names":["johngeorgewright/config","jg-wright/targetd"],"tags_count":174,"template":false,"template_full_name":"johngeorgewright/ts-mono-repo","purl":"pkg:github/jg-wright/targetd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-wright%2Ftargetd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-wright%2Ftargetd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-wright%2Ftargetd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-wright%2Ftargetd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jg-wright","download_url":"https://codeload.github.com/jg-wright/targetd/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jg-wright%2Ftargetd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34155422,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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-06-10T14:02:26.326Z","updated_at":"2026-06-10T14:02:27.234Z","avatar_url":"https://github.com/jg-wright.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @targetd\n\nA powerful, type-safe targeting and feature flag system for dynamically serving\ndifferent content based on query conditions.\n\n## Overview\n\n`@targetd` is a TypeScript-first monorepo providing a complete solution for\nbuilding context-aware applications with dynamic content delivery. Perfect for\nfeature flags, A/B testing, content personalization, and configuration\nmanagement.\n\n**Key Features:**\n\n- 🎯 **Type-safe targeting** - Full TypeScript inference and runtime validation\n  with [Zod](https://zod.dev)\n- ⚡ **High performance** - In-memory data store optimized for speed\n- 🔌 **Modular architecture** - Use only what you need with focused packages\n- 🌐 **HTTP-ready** - Built-in server and client for distributed systems\n- 📁 **File-based rules** - Load rules from JSON/YAML files with hot-reloading\n- 🎨 **Extensible** - Custom targeting descriptors and predicates\n\n## Packages\n\n### [@targetd/api](./packages/api)\n\nCore targeting and data querying API. Define payloads, targeting rules, and\nquery logic.\n\n```typescript\nimport { Data, DataSchema, targetIncludes } from '@targetd/api'\nimport { z } from 'zod'\n\nconst schema = DataSchema.create()\n  .usePayload({ greeting: z.string() })\n  .useTargeting({ country: targetIncludes(z.string()) })\n\nconst data = await Data.create(schema).addRules('greeting', [\n  { targeting: { country: ['US'] }, payload: 'Hello!' },\n  { targeting: { country: ['ES'] }, payload: '¡Hola!' },\n  { payload: 'Hi!' },\n])\n\nawait data.getPayload('greeting', { country: 'US' }) // 'Hello!'\n```\n\n**[View Documentation →](./packages/api)**\n\n### [@targetd/server](./packages/server)\n\nHTTP server for exposing `@targetd/api` data over REST endpoints.\n\n```typescript\nimport { createServer } from '@targetd/server'\n\ncreateServer(data).listen(3000)\n// GET /greeting?country=US → \"Hello!\"\n```\n\n**[View Documentation →](./packages/server)**\n\n### [@targetd/client](./packages/client)\n\nType-safe HTTP client for querying `@targetd/server` instances.\n\n```typescript\nimport { Client } from '@targetd/client'\n\nconst client = await Client.create('http://localhost:3000', schema)\nconst greeting = await client.getPayload('greeting', { country: 'US' })\n```\n\n**[View Documentation →](./packages/client)**\n\n### [@targetd/fs](./packages/fs)\n\nLoad targeting rules from JSON/YAML files with hot-reloading support.\n\n```typescript\nimport { load, watch } from '@targetd/fs'\n\nconst data = await load(baseData, './rules')\nwatch(baseData, './rules', (error, updatedData) =\u003e {\n  // Rules automatically reload on file changes\n})\n```\n\n**[View Documentation →](./packages/fs)**\n\n### [@targetd/date-range](./packages/date-range)\n\nBuilt-in targeting descriptor for date range queries.\n\n```typescript\nimport dateRangeTargeting from '@targetd/date-range'\n\nconst schema = DataSchema.create()\n  .usePayload({ campaign: z.string() })\n  .useTargeting({ date: dateRangeTargeting })\n\nconst data = await Data.create(schema).addRules('campaign', [\n  {\n    targeting: { date: { start: '2024-12-01', end: '2024-12-31' } },\n    payload: 'Holiday Campaign',\n  },\n])\n```\n\n**[View Documentation →](./packages/date-range)**\n\n### [@targetd/explode](./packages/explode)\n\nTransform flat key notation to nested objects.\n\n```typescript\nimport { explode } from '@targetd/explode'\n\nexplode({ 'user.name': 'John' })\n// { user: { name: 'John' } }\n```\n\n**[View Documentation →](./packages/explode)**\n\n### [@targetd/json-schema](./packages/json-schema)\n\nGenerate JSON Schema from Zod schemas for documentation and validation.\n\n**[View Documentation →](./packages/json-schema)**\n\n## Quick Start\n\n### Installation\n\n```bash\n# Core API\nnpm install zod \u0026\u0026 npx jsr add @targetd/api\n\n# With server and client\nnpx jsr add @targetd/api @targetd/server @targetd/client\n\n# With file loading\nnpx jsr add @targetd/api @targetd/fs\n```\n\n### Basic Example\n\n**1. Define your data:**\n\n```typescript\nimport { Data, DataSchema, targetIncludes } from '@targetd/api'\nimport { z } from 'zod'\n\nconst schema = DataSchema.create()\n  .usePayload({\n    banner: z.string(),\n    feature: z.object({\n      enabled: z.boolean(),\n      maxUsers: z.number(),\n    }),\n  })\n  .useTargeting({\n    platform: targetIncludes(z.string()),\n    isPremium: targetIncludes(z.boolean()),\n  })\n\nexport const data = await Data.create(schema)\n  .addRules('banner', [\n    { targeting: { platform: ['mobile'] }, payload: '📱 Mobile Banner' },\n    { targeting: { platform: ['desktop'] }, payload: '🖥 Desktop Banner' },\n    { payload: 'Default Banner' },\n  ])\n  .addRules('feature', [\n    {\n      targeting: { isPremium: [true] },\n      payload: { enabled: true, maxUsers: 1000 },\n    },\n    { payload: { enabled: true, maxUsers: 10 } },\n  ])\n```\n\n**2. Start a server:**\n\n```typescript\nimport { createServer } from '@targetd/server'\nimport { data } from './data.ts'\n\ncreateServer(data).listen(3000)\n```\n\n**3. Query from a client:**\n\n```typescript\nimport { Client } from '@targetd/client'\nimport { data } from './data.ts'\n\nconst client = new Client('http://localhost:3000', data)\n\n// Type-safe queries\nconst banner = await client.getPayload('banner', { platform: 'mobile' })\nconst allPayloads = await client.getPayloadForEachName({ isPremium: true })\n```\n\n## Use Cases\n\n### Feature Flags\n\n```typescript\nconst data = await Data.create(\n  DataSchema.create()\n    .usePayload({ newFeature: z.boolean() })\n    .useTargeting({ userTier: targetEquals(z.string()) }),\n).addRules('newFeature', [\n  { targeting: { userTier: 'beta' }, payload: true },\n  { payload: false },\n])\n```\n\n### A/B Testing\n\n```typescript\nconst data = await Data.create(\n  DataSchema.create()\n    .usePayload({ variant: z.string() })\n    .useTargeting({ userId: targetIncludes(z.string()) }),\n).addRules('variant', [\n  { targeting: { userId: experimentGroup }, payload: 'variant-a' },\n  { payload: 'variant-b' },\n])\n```\n\n### Content Personalization\n\n```typescript\nconst data = await Data.create(\n  DataSchema.create()\n    .usePayload({ content: z.string() })\n    .useTargeting({\n      region: targetIncludes(z.string()),\n      language: targetIncludes(z.string()),\n    }),\n).addRules('content', [\n  {\n    targeting: { region: ['US'], language: ['en'] },\n    payload: 'US English content',\n  },\n  {\n    targeting: { region: ['US'], language: ['es'] },\n    payload: 'US Spanish content',\n  },\n  { payload: 'Default content' },\n])\n```\n\n### Configuration Management\n\n```typescript\nconst data = await Data.create(\n  DataSchema.create()\n    .usePayload({\n      config: z.object({\n        apiUrl: z.string(),\n        timeout: z.number(),\n      }),\n    })\n    .useTargeting({ environment: targetEquals(z.string()) }),\n).addRules('config', [\n  {\n    targeting: { environment: 'production' },\n    payload: { apiUrl: 'https://api.prod.com', timeout: 5000 },\n  },\n  {\n    targeting: { environment: 'staging' },\n    payload: { apiUrl: 'https://api.staging.com', timeout: 10000 },\n  },\n  { payload: { apiUrl: 'http://localhost:3000', timeout: 30000 } },\n])\n```\n\n## Core Concepts\n\n### Schema Configuration\n\nUse `DataSchema` to declare payload schemas and targeting descriptors, then pass\nthe resulting schema directly to `Data.create()`. Splitting the schema and data\nphases keeps TypeScript compilation cheap even with hundreds of payloads and\ntargeting descriptors.\n\n### Payloads\n\nDefine what data you want to serve using Zod schemas.\n\n### Targeting\n\nSpecify conditions that determine which payload to serve using predicates like\n`targetIncludes` and `targetEquals`, or create custom ones.\n\n### Rules\n\nMap targeting conditions to payloads. Rules are evaluated in order—first match\nwins.\n\n### Variables\n\nReusable values with their own targeting rules that can be referenced in\npayloads using `{{variableName}}` syntax.\n\n### Fall-through Targeting\n\nPass unresolved targeting conditions between services for evaluation in\ndistributed systems.\n\n## Architecture\n\n```\n┌─────────────────┐\n│   @targetd/api  │  Core targeting engine\n└────────┬────────┘\n         │\n    ┌────┴────┐\n    │         │\n┌───▼────┐ ┌─▼──────────┐\n│ server │ │ file loaders│\n└───┬────┘ └────────────┘\n    │\n┌───▼────┐\n│ client │\n└────────┘\n```\n\n## Documentation\n\n- [API Documentation](./packages/api/README.md)\n- [Server Documentation](./packages/server/README.md)\n- [Client Documentation](./packages/client/README.md)\n- [File System Loader Documentation](./packages/fs/README.md)\n- [Date Range Targeting Documentation](./packages/date-range/README.md)\n- [Explode Utility Documentation](./packages/explode/README.md)\n- [JSON Schema Documentation](./packages/json-schema/README.md)\n\n## Contributing\n\nThis is a monorepo managed with\n[Deno workspaces](https://deno.land/manual/basics/workspaces).\n\n### Development\n\n```bash\n# Install dependencies\ndeno install\n\n# Run tests\ndeno task test\n\n# Run tests for specific package\ncd packages/api \u0026\u0026 deno task test\n```\n\n## License\n\nSee individual package LICENSE files for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjg-wright%2Ftargetd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjg-wright%2Ftargetd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjg-wright%2Ftargetd/lists"}