Skip to content

Conversation

@ian
Copy link
Owner

@ian ian commented Oct 26, 2025

  • Refactor @startupkit/analytics to minimal core with peer dependencies
  • Update @startupkit/auth to use flexible peer dependencies (>=1.3.0)
  • Update @repo/analytics to import directly from posthog-js and rudderstack
  • Update @repo/auth to import directly from better-auth
  • Remove version lock-in - projects control all upstream dependencies
  • Add comprehensive documentation of shadcn principle
  • Both packages build successfully

The shadcn principle: Import directly from upstream. Only use @startupkit/*
when it adds real value (utilities, orchestration, conventions).

Closes STARTUP-93


Summary by cubic

Refactors packages to shadcn-style direct imports so projects control upstream versions and avoid lock-in. Implements STARTUP-93 by slimming @startupkit/* to minimal utilities, pushing product code to @repo/*, and updating docs, CLI, and scripts.

  • Refactors

    • @startupkit/analytics → minimal core: peer deps, new orchestrator/utils/types; removed built-in plugins; provider now forwards to passed plugins.
    • @startupkit/auth → flexible peer deps (better-auth >=1.3.0; relaxed Next/React ranges).
    • @repo/analytics → direct imports (posthog-js, RudderStack), type-safe client/server tracking and feature flags; now the recommended product analytics (docs updated).
    • @repo/auth → direct better-auth; server uses createAuth helper; provider wires identify/reset to analytics.
    • Docs → added PACKAGE_STRATEGY and QUICK_REFERENCE; @startupkit/analytics marked legacy (marketing-only) with migration guidance.
  • New Features

    • CLI add: choose Local (@repo/) vs Centralized (@startupkit/), places files in the right folder, and prints next steps.
    • Version bump script: clearer output, updates template/app references to the new version, and commits changes.

- Refactor @startupkit/analytics to minimal core with peer dependencies
- Update @startupkit/auth to use flexible peer dependencies (>=1.3.0)
- Update @repo/analytics to import directly from posthog-js and rudderstack
- Update @repo/auth to import directly from better-auth
- Remove version lock-in - projects control all upstream dependencies
- Add comprehensive documentation of shadcn principle
- Both packages build successfully

The shadcn principle: Import directly from upstream. Only use @startupkit/*
when it adds real value (utilities, orchestration, conventions).

Closes STARTUP-93
@linear
Copy link

linear bot commented Oct 26, 2025

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 issues found across 31 files

Prompt for AI agents (all 8 issues)

Understand the root cause of the following 8 issues and fix them.


<file name="packages/analytics/package.json">

<violation number="1" location="packages/analytics/package.json:40">
Emptying the dependencies object removes the externals list that rollup.config.mjs derives from pkg.dependencies, so analytics/posthog-js will now be bundled instead of treated as peer deps—undoing the intended refactor.</violation>
</file>

<file name="REFACTOR_SUMMARY.md">

<violation number="1" location="REFACTOR_SUMMARY.md:87">
The example calls `rudderstack.track(...)` without defining a `rudderstack` instance, so readers copying this snippet will hit a ReferenceError. Consider either instantiating `RudderAnalytics` or updating the example to use the imported symbol correctly.</violation>
</file>

<file name="packages/analytics/src/AnalyticsProvider.tsx">

<violation number="1" location="packages/analytics/src/AnalyticsProvider.tsx:34">
Calling plugin.initialize inside useMemo runs during render, so Strict Mode will execute it twice and duplicate analytics initialization. Move this side effect into useEffect or similar lifecycle-safe code.</violation>
</file>

<file name="templates/repo/packages/analytics/README.md">

<violation number="1" location="templates/repo/packages/analytics/README.md:64">
The client `track` example calls the hook with a string event, but `useAnalytics().track` currently expects `never`, so this sample fails TypeScript checks.</violation>

<violation number="2" location="templates/repo/packages/analytics/README.md:74">
`getFeatureFlags` is not exported from `@repo/analytics`; this import example will crash when followed.</violation>
</file>

<file name="packages/analytics/README.md">

<violation number="1" location="packages/analytics/README.md:43">
The README usage example imports `@startupkit/analytics/ga`, `/plausible`, and `/posthog`, but those modules are not present in this package, so the documented setup will fail at runtime.</violation>
</file>

<file name="packages/analytics/src/types.ts">

<violation number="1" location="packages/analytics/src/types.ts:7">
Allowing plugins to return Promise&lt;void&gt; from track means an async plugin rejection will bubble out, but createAnalyticsOrchestrator just invokes plugin.track(...) without awaiting or catch. Either restrict this to void or update the orchestrator to handle the returned promise.</violation>
</file>

<file name="templates/repo/packages/auth/src/index.ts">

<violation number="1" location="templates/repo/packages/auth/src/index.ts:13">
Removing the email OTP client plugin from the auth client breaks the documented OTP sign-in flow; please restore an OTP plugin alongside the admin plugin.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

const { track } = useAnalytics();

const handleClick = () => {
track("BUTTON_CLICKED", { buttonId: "cta" });
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The client track example calls the hook with a string event, but useAnalytics().track currently expects never, so this sample fails TypeScript checks.

Prompt for AI agents
Address the following comment on templates/repo/packages/analytics/README.md at line 64:

<comment>The client `track` example calls the hook with a string event, but `useAnalytics().track` currently expects `never`, so this sample fails TypeScript checks.</comment>

<file context>
@@ -21,21 +48,212 @@ await track({
+  const { track } = useAnalytics();
+
+  const handleClick = () =&gt; {
+    track(&quot;BUTTON_CLICKED&quot;, { buttonId: &quot;cta&quot; });
+  };
+
</file context>
Fix with Cubic

ian added 22 commits October 26, 2025 16:13
- Remove @startupkit/analytics entirely (not needed)
- Remove RudderStack dependency (PostHog handles everything)
- Update @startupkit/auth to use flexible peer dependencies (>=1.3.0)
- Update @repo/analytics to import directly from posthog-js/posthog-node
- Update @repo/auth to import directly from better-auth
- Add comprehensive package strategy documentation
- Add withAuth and handler exports to @repo/auth/server
- Fix email template props and types

The shadcn principle: Import directly from upstream libraries.
Only use @startupkit/* when it adds real value (like @startupkit/auth helpers).

Benefits:
- No version lock-in - upgrade posthog/better-auth anytime
- You own the code - @repo/* packages are yours to customize
- Simpler architecture - PostHog only, no RudderStack
- Better TypeScript support with direct imports

Closes STARTUP-93
- Upgrade Next.js from 15.3.0 to 16.0.0
- Update @types/node to 22.12.0 (for vite compatibility)
- Update @types/react to 19.0.1
- Update @types/react-dom to 19.0.2
- Fix @startupkit/auth peer dependency to support Next.js >=14.0.0
- React 19 peer warnings from Radix UI are expected (React 19 is backward compatible)
The adminClient and emailOTPClient plugins have complex type signatures
that require type assertions to work properly. This is a better-auth
type system limitation.
@ian ian changed the base branch from main to 0.5.X October 26, 2025 10:01
@ian ian merged commit 7846bd2 into 0.5.X Oct 26, 2025
6 checks passed
@ian ian deleted the startup-93-figure-out-packages-strategy branch October 26, 2025 10:40
@linear
Copy link

linear bot commented Oct 26, 2025

ian added a commit that referenced this pull request Nov 3, 2025
* Refactor to shadcn-style direct imports (STARTUP-93) (#24)

* feat: refactor to shadcn-style direct imports (STARTUP-93)

- Refactor @startupkit/analytics to minimal core with peer dependencies
- Update @startupkit/auth to use flexible peer dependencies (>=1.3.0)
- Update @repo/analytics to import directly from posthog-js and rudderstack
- Update @repo/auth to import directly from better-auth
- Remove version lock-in - projects control all upstream dependencies
- Add comprehensive documentation of shadcn principle
- Both packages build successfully

The shadcn principle: Import directly from upstream. Only use @startupkit/*
when it adds real value (utilities, orchestration, conventions).

Closes STARTUP-93

* lockfile

* lockfile

* lint

* fixes

* lint

* drop top level analytics

* fix

* lockfile

* typecheck

* feat: implement shadcn-style package strategy (STARTUP-93)

- Remove @startupkit/analytics entirely (not needed)
- Remove RudderStack dependency (PostHog handles everything)
- Update @startupkit/auth to use flexible peer dependencies (>=1.3.0)
- Update @repo/analytics to import directly from posthog-js/posthog-node
- Update @repo/auth to import directly from better-auth
- Add comprehensive package strategy documentation
- Add withAuth and handler exports to @repo/auth/server
- Fix email template props and types

The shadcn principle: Import directly from upstream libraries.
Only use @startupkit/* when it adds real value (like @startupkit/auth helpers).

Benefits:
- No version lock-in - upgrade posthog/better-auth anytime
- You own the code - @repo/* packages are yours to customize
- Simpler architecture - PostHog only, no RudderStack
- Better TypeScript support with direct imports

Closes STARTUP-93

* revert

* revert

* revert

* chore: upgrade to Next.js 16.0.0 and React 19

- Upgrade Next.js from 15.3.0 to 16.0.0
- Update @types/node to 22.12.0 (for vite compatibility)
- Update @types/react to 19.0.1
- Update @types/react-dom to 19.0.2
- Fix @startupkit/auth peer dependency to support Next.js >=14.0.0
- React 19 peer warnings from Radix UI are expected (React 19 is backward compatible)

* bump next/react

* add otp client again

* fix readme

* fix: add type assertions for better-auth client plugins

The adminClient and emailOTPClient plugins have complex type signatures
that require type assertions to work properly. This is a better-auth
type system limitation.

* cleanup

* wip analytics package

* analytics clenaup

* lockfile

* remove markdown spam

* lint

* package

* fix type errors

* actually error on pnpm install fail

* fix repo where we pull templates from

* better phrase

* Ditch prisma, switch to drizzle (#25)

* switch to drizzle

* fix: add allowEmptyPaths to replace-in-file to handle edge cases

Addresses STARTUP-92

* fix: prevent duplicate /templates/repo in degit source path

When --repo includes /templates/repo with a branch, don't append it again.

Addresses STARTUP-92

* feat: export TypeScript types from Drizzle schema

Export User, Account, Session, Team, TeamMember, and Verification types
for use by other packages.

Addresses STARTUP-92

* fix: add drizzle-orm dependency and fix AuthConfig types

- Add drizzle-orm to @repo/auth dependencies
- Update AuthConfig users type to accept table definitions

Addresses STARTUP-92

* fix: use Record<string, never> for users type to allow build

The more restrictive type with unknown fields was preventing TypeScript
from compiling the eq() operations with Drizzle columns.

Addresses STARTUP-92

* fix: use any type for users to accept Drizzle table types

Record<string, never> was too restrictive and prevented Drizzle
PgTableWithColumns from being assigned. Using any allows full compatibility.

Addresses STARTUP-92

* fix: use proper Drizzle PgTableWithColumns type instead of any

Import PgTableWithColumns from drizzle-orm/pg-core for type safety
while maintaining compatibility with Drizzle table structures.

Addresses STARTUP-92

* fix: use minimal type interface for users parameter

Avoid importing Drizzle types in @startupkit/auth to prevent
version conflicts between package and template instances.
Use minimal interface with just { id: unknown } since that's
all we need for the eq() operation.

Addresses STARTUP-92

* fix: use generic object type with ts-expect-error for Drizzle tables

Use TUsers extends object as a generic parameter to accept Drizzle
tables without importing Drizzle types (which causes version conflicts).
Use @ts-expect-error for accessing users.id in implementation since
TypeScript can't verify the generic has this property at compile time,
but it will exist at runtime.

This avoids any/unknown types while maintaining type safety.

Addresses STARTUP-92

* adding centralized config

* refactor auth

* get rid of erroneous docs

* fix types

* readme updated, type fixes

* update readme

* add biome to packages (#27)

* add biome

* adding biome

* fixing lint

* fix lint

* lint typecheck step

* lint fix

* fix typecheck

* lint

* Add agents.md management (#28)

* adding ruler for agents

* add missing gemini and qwen

* ignore

* fix gitignore

* baseline ruler

* wip agents.md

* updates

* add missing ignores for template

* set prefs for startupkit agents

* remove jobs (#29)

* remove (#30)

* remove

* fix tests

* run parallel

* cleanup

* rename

* rename (#31)

* Remove packages/utils (#32)

* remove utils we dont need this anymore:

* more

* remove this junk

* Add OpenPanel (#33)

* add openpanel

* memo

* lint

* fixing typecheck

* adding link/unlink

* convert github action to use script

* make proper react component

* refactor openpanel

* we've ported readme to public repo, we can remove this

* Next@16 (#34)

* Refactor project configuration and dependencies

- Removed ESLint configuration file (.eslintrc.json).
- Updated Next.js configuration in apps/home/next.config.mjs to use turbopack and simplified rewrites.
- Changed build script in apps/home/package.json to use webpack.
- Updated package dependencies in apps/home/package.json to use catalog references for various libraries.
- Modified TypeScript configuration in apps/home/tsconfig.json to include target and updated JSX settings.
- Updated pnpm-lock.yaml with new package versions and resolved dependencies.
- Adjusted workspace configuration in pnpm-workspace.yaml to include new catalogs and dependencies.
- Cleaned up template configurations for Next.js to align with new standards.

* use sk next tsconfig

* fix next tsconfig

* fix

* fixes

* fixes

* lint

* remove webpack and turbo not required

* Adding GA, refactor OpenMeter (#35)

* adding GA

* Refactor GA

* moving openpanel

* add missing

* refactor

* much simpler analytics setup

* remove dupe openpanel

* fix, lint

* cleanup

* lint

* simplify

* fix

* add second param

* fix email, fixes STARTUP-103

* Adding ahrefs provider (#36)

* adding ahrefs

* lint

* lockfile

* mby fix

* remove admin client for now
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants