This FRD ships @dmwd-io/analytics as an optional package that re-exports posthog-js and posthog-node as the platform standard for product analytics via PostHog. The value is standards and drift prevention, not a custom abstraction. No custom provider interface is built — the library’s own API is the interface, per ADR-014.
Introduction
Overview
Per ADR-014 (Open Source First), the platform designates posthog-js and posthog-node as the community libraries for product analytics rather than building a custom AnalyticsProvider interface. The @dmwd-io/analytics package re-exports these libraries as thin wrappers and documents the platform env var conventions (POSTHOG_API_KEY, POSTHOG_HOST). Apps that today scatter direct PostHog imports or use inconsistent event naming conventions converge on a single import path and documented conventions without an extra abstraction layer.
Goals
Designate posthog-js / posthog-node as the platform standard for product analytics per ADR-027 §5 and ADR-014.
Ship @dmwd-io/analytics as a thin re-export package so all apps import from one canonical path.
Document POSTHOG_API_KEY and POSTHOG_HOST as the platform env var names.
Enforce an event naming convention ({domain}.{action}) matching the wide-events standard from ADR-023.
Document privacy-conscious defaults: no PII in event properties unless explicitly opted in.
Include examples showing standard PostHog integration using the @dmwd-io/analytics import path.
Non-Goals
Building a custom provider interface or adapter layer — the library’s own API is the interface (per ADR-014).
Mixpanel or Google Analytics adapters (not designated by ADR-027).
Implementing a custom mock adapter — use PostHog’s built-in testing utilities or vi.mock.
Building analytics dashboards or reporting UI.
A/B test assignment or experiment tracking (see FRD: Feature Flags Provider).
Revenue or conversion tracking beyond standard event properties.
Scope
In Scope
Area
Description
@dmwd-io/analytics package
Thin re-export of posthog-js and posthog-node; canonical import path for all apps
Env var conventions
POSTHOG_API_KEY and POSTHOG_HOST documented as platform standard names
Privacy defaults
Documentation of PII-safe defaults; guidance on avoiding PII in event properties
Event naming
Convention: {domain}.{action} format per ADR-023; documented, not enforced at runtime
Integration examples
Storybook docs showing PostHog initialization and event calls via @dmwd-io/analytics
Out of Scope
Area
Reason
Custom provider interface
ADR-014 prohibits building one when the community library’s API suffices
Custom adapter or factory pattern
Library handles this natively
Mixpanel or Google Analytics adapters
Not designated by ADR-027
Custom mock adapter
Use PostHog’s testing utilities or vi.mock
Analytics dashboards
Vendor-hosted
A/B test tracking
Covered by feature flags provider
Session recording
Separate vendor capability
Users and Pain Points
User Groups
User
Description
Needs
App developers
Engineers instrumenting product analytics
A canonical import path and documented conventions for PostHog
QA engineers
Testers verifying analytics fire correctly
Clear guidance on mocking PostHog in tests
Product managers
Stakeholders analyzing user behavior
Consistent event naming and property schemas across apps
Pain Points
User
Pain Point
Impact
App developers
Each app imports PostHog directly with different initialization patterns
Inconsistent configuration; env var names vary across apps
App developers
No shared guidance on testing analytics calls
Analytics regressions (missing events, wrong properties) go undetected
Product managers
Event names vary across apps — button_click vs ButtonClicked vs ui.button.click
Dashboard queries break; analysis requires manual name mapping
App developers
PII accidentally ends up in analytics events (email in properties, names in traits)
Privacy compliance violations
Definitions
Term
Definition
Track
Record a named event with properties (e.g. billing.plan_upgraded)
Identify
Associate the current user with a user ID and traits (name, plan, role)
Group
Associate the current user with a group/organization with traits
Page
Record a page view with URL and properties
Reset
Clear the current user identity (on sign-out)
Consent
User’s opt-in/opt-out status for analytics collection
PII
Personally identifiable information: email, phone, IP address, full name
Current State
Existing Behavior
No shared analytics abstraction exists. Apps import posthog-js or other vendor SDKs directly in components and utility files. Event names, property schemas, and user identification patterns vary across apps. No privacy safeguards exist at the analytics layer — developers must manually avoid passing PII.
Current Limitations
No canonical import path — apps wire PostHog with different initialization patterns.
No documented env var names — POSTHOG_API_KEY vs NEXT_PUBLIC_POSTHOG_KEY vs other names appear across apps.
No event naming convention — each app invents its own schema.
No PII guidance — sensitive data leaks into analytics properties.
No shared testing guidance — tests mock PostHog globals inconsistently.
Existing Workarounds
Apps create ad-hoc wrapper functions around PostHog calls.
Test files mock window.posthog globals inconsistently.
Privacy reviews manually audit analytics calls before release.
Proposed Solution
Summary
Per ADR-014 (Open Source First), @dmwd-io/analytics is a thin re-export package. It re-exports posthog-js and posthog-node as-is, documents the platform env var names (POSTHOG_API_KEY, POSTHOG_HOST), and provides usage examples. No custom interface is built — the library’s API is the interface.
import { PostHog } from'@dmwd-io/analytics';
The package adds platform conventions on top of the library without wrapping or replacing it.
Key Capabilities
@dmwd-io/analytics re-exports posthog-js (browser) and posthog-node (server) from a single package.
Platform env var names: POSTHOG_API_KEY and POSTHOG_HOST.
Event naming convention documented: {domain}.{action} per ADR-023.
No custom runtime code beyond the re-export and any platform-specific initialization helper.
User Experience
End users are not directly affected. The package powers analytics instrumentation behind the scenes. Users benefit from privacy-conscious defaults documented for developers.
Developer Experience
Developers import from @dmwd-io/analytics instead of posthog-js directly. Initialization follows the documented POSTHOG_API_KEY / POSTHOG_HOST pattern. Event naming follows {domain}.{action}. Testing uses PostHog’s own test utilities or vi.mock — no custom mock adapter is needed.
Requirements
ID
Requirement
Priority
Notes
FR-001
@dmwd-io/analytics re-exports posthog-js and posthog-node
Must
-
FR-002
Platform env var names POSTHOG_API_KEY and POSTHOG_HOST are documented
Must
-
FR-003
Event naming convention {domain}.{action} is documented with examples
Must
Per ADR-023
FR-004
PII avoidance guidance is documented for event properties
Must
-
FR-005
Storybook docs page shows PostHog initialization using @dmwd-io/analytics
Must
-
FR-006
Testing guidance documents how to mock PostHog using vi.mock or PostHog test utilities
Should
-
Priority Definitions
Priority
Meaning
Must
Required for this feature to ship.
Should
Important, but can be deferred if needed.
Could
Nice to have. Not required for initial release.
Functional Requirements
ID
Requirement
User Benefit
Priority
FUNC-001
import { posthog } from '@dmwd-io/analytics' works in browser contexts
Single import path for all apps
Must
FUNC-002
import { PostHog } from '@dmwd-io/analytics/node' works in server/Node contexts
Server-side analytics via the same package
Must
FUNC-003
Docs show posthog.identify(userId, { name, plan }) with PII guidance
User-level analytics with privacy context
Must
FUNC-004
Docs show posthog.capture('billing.plan_upgraded', { planId }) with naming convention
Consistent event tracking across apps
Must
FUNC-005
Docs show PostHog initialization using POSTHOG_API_KEY and POSTHOG_HOST
Consistent env var usage across apps
Must
FUNC-006
Docs show how to mock PostHog in Vitest using vi.mock
Test-time analytics verification
Should
Non-Functional Requirements
ID
Requirement
Category
Priority
NFR-001
The package adds zero custom runtime code beyond the re-export
Maintainability
Must
NFR-002
posthog-js and posthog-node are peer dependencies, not bundled
Performance
Must
NFR-003
Package does not introduce a breaking API change relative to posthog-js
Compatibility
Must
NFR-004
Analytics calls must never throw — this is posthog-js’s own behavior, documented
Reliability
Must
API / Interface Requirements
Public API
The public API is posthog-js / posthog-node’s own API, re-exported. No new types or functions are added by the package itself. The platform layer adds only:
The library’s API is the interface — no wrapper functions are exported.
PII fields (email, phone, ip) should be omitted from event properties; PostHog person profiles handle identity separately.
Event names follow {domain}.{action} per ADR-023.
Accessibility Requirements
ID
Requirement
Notes
A11Y-001
Package is a data layer with no UI — accessibility requirements do not apply directly
No UI components
Checklist
Keyboard support is defined. (N/A — no UI)
Focus behavior is defined. (N/A — no UI)
Screen reader behavior is defined. (N/A — no UI)
Color contrast requirements are met. (N/A — no UI)
Reduced motion behavior is considered. (N/A — no UI)
Semantic HTML expectations are documented. (N/A — no UI)
ARIA usage is defined only where needed. (N/A — no UI)
Content and Documentation Requirements
ID
Requirement
Location
Priority
DOC-001
Storybook docs page explaining the platform standard and @dmwd-io/analytics import path
Storybook
Must
DOC-002
Env var reference: POSTHOG_API_KEY, POSTHOG_HOST
Storybook
Must
DOC-003
Example: browser initialization and event capture
Storybook
Must
DOC-004
Example: server-side initialization with posthog-node
Storybook
Must
DOC-005
Example: testing analytics calls with vi.mock
Storybook
Should
DOC-006
PII avoidance guidance with concrete do/don’t examples
Storybook
Must
Dependencies
Dependency
Type
Owner
Status
Notes
ADR-051 provider pattern
Architecture
Engineering
Ready
Defines contract structure
ADR-023 wide events logging
Architecture
Engineering
Ready
Defines {domain}.{action} naming convention
ADR-027 default tech stack
Architecture
Engineering
Ready
Designates PostHog (self-host) as the product analytics default
ADR-014 open source first
Architecture
Engineering
Ready
Requires adopting community library API rather than building custom interface
Risks and Tradeoffs
Risk / Tradeoff
Impact
Mitigation
posthog-js API changes break consuming apps
Breaking change propagates through @dmwd-io/analytics
Pin a major version range; document upgrade path
PII guidance is documentation-only, not enforced at runtime
Sensitive data may still leak
Lint rule or PR checklist item to review analytics calls
Thin re-export adds little value if apps ignore the canonical import
Drift continues
Enforce via lint rule requiring @dmwd-io/analytics import, not direct posthog-js
No server-side analytics in v1
Server-rendered pages cannot track events
posthog-node re-export covers this natively
Open Questions
ID
Question
Owner
Status
Resolution
Q-001
Should the package export a platform-specific initPostHog helper to enforce env var names?
David Holmes
Open
—
Q-002
Should the PII guidance be enforced via an ESLint rule rather than documentation?
David Holmes
Open
—
Q-003
Should @dmwd-io/analytics be a separate npm package or a path export from the design system?
David Holmes
Open
—
Acceptance Criteria
ID
Criteria
Related Requirement
AC-001
import posthog from '@dmwd-io/analytics' resolves to posthog-js without error
FR-001
AC-002
import { PostHog } from '@dmwd-io/analytics/node' resolves to posthog-node without error
FR-001
AC-003
POSTHOG_API_KEY and POSTHOG_HOST are documented as the platform env var names
FR-002
AC-004
Storybook docs page shows initialization and event capture examples
FR-005
AC-005
No custom provider interface, adapter, or factory function is shipped in the package
ADR-014
AC-006
pnpm typecheck passes with no errors
NFR-001
LLM Handoff Instructions
Expected LLM Behavior
Create the @dmwd-io/analytics package (or path export) structure.
Add a package.json with posthog-js and posthog-node as peer dependencies.
Create src/index.ts that does export { default } from 'posthog-js'; export * from 'posthog-js';.
Create src/node.ts that does export * from 'posthog-node';.
Document POSTHOG_API_KEY and POSTHOG_HOST as the platform env var names in the Storybook docs page.
Run pnpm typecheck to confirm no type errors.
LLM Should Not
Build a custom AnalyticsProvider interface, adapter, factory function, or mock — per ADR-014.
Import posthog-js or posthog-node anywhere except the re-export files.
Add runtime logic beyond the re-export and any optional initialization helper.
Build Mixpanel or Google Analytics adapters.
Decision Log
Date
Decision
Reason
Owner
2026-05-26
Fire-and-forget (synchronous void) API
Analytics must never block UI rendering or throw errors that break the app
David Holmes
2026-05-26
PII sanitizer enabled by default
Privacy-by-default is the correct stance; developers can opt in to sending PII explicitly
David Holmes
2026-05-26
{domain}.{action} event naming per ADR-023
Consistent naming across analytics and logging enables cross-system correlation
David Holmes
2026-05-26
PostHog designated as the analytics adapter
ADR-027 §5 designates PostHog (self-host) as the product analytics default; separate from wide-event logging
David Holmes
2026-06-02
Reframed per ADR-014 (Open Source First): adopt posthog-js / posthog-node as thin re-export rather than building a custom provider interface. Library API is the interface.
ADR-014 prohibits building custom abstractions when a well-maintained community library covers the use case
David Holmes
Document History
Date
Author
Change
2026-05-26
David Holmes
Initial draft
2026-06-02
David Holmes
Reframed per ADR-014: ship as thin re-export of posthog-js / posthog-node, drop custom interface.