Skip to content
OTFotf

Contributing

How to file issues, propose changes, and add components to the OTF SDK.

The OTF SDK is MIT-licensed and open. The kits are commercial. This page is about contributing to the SDK side.

Where to file things

KindWhere
Bug in @otfdashkit/{ui, ui-native, tokens}github.com/otf-kit/sdk/issues
Component requestOpen a Discussion on the SDK repo with the use case + a sketch of the API
Docs typo / clarificationPR the relevant .mdx in apps/docs/content/
QuestionGitHub Discussions — we read everything
Bug in a paid kitEmail support after purchase; private kit repos have an issue tracker

Local setup

git clone git@github.com:otf-kit/sdk.git
cd sdk
pnpm install

Then pick what you're working on:

GoalCommand
Storybook (web components)pnpm --filter @otfdashkit/storybook-web dev
Storybook (native components)pnpm --filter @otfdashkit/storybook-native dev
Native showcase apppnpm --filter @otfdashkit/ui-native-showcase dev
Docs sitepnpm --filter @otfdashkit/docs dev
Build a single packagepnpm --filter @otfdashkit/<pkg> build
Type-check the whole repopnpm type-check
Lint the whole repopnpm lint

Commit conventions

We use Conventional Commits:

  • feat(ui): add Marquee primitive — new feature
  • fix(ui-native): center BottomSheet snap points — bug fix
  • docs: clarify token CSS load order — docs only
  • chore(deps): bump fumadocs-ui — chores
  • refactor(ui): split data-grid into rendering + state — internal change

Scope is the package name without the org prefix (ui, ui-native, tokens, docs, storybook-web, storybook-native).

Adding a component

  1. Open a Discussion first. Don't surprise us with a 1000-line PR for a component we wouldn't merge. We're stricter about what ships than most libraries because the SDK feeds the paid kits — every new component is a long-term maintenance commitment.

  2. Write Storybook stories before the component is final. Real usage flushes out API issues that look fine in isolation.

  3. Follow the file convention. kebab-case.tsx filename, PascalCase exported identifiers, single file per component (no index.ts re-exports inside the component folder).

  4. Read tokens, don't redefine them. No hardcoded hex. No inline style={{ background: ... }}. @otfdashkit/eslint-plugin-otf-design will flag both.

  5. Test against the four shipped themes. A component that looks great in theme-slate dark and breaks in theme-warm light isn't done.

  6. Document on the same PR. Update the relevant apps/docs/content/docs/components/.../*.mdx in the same PR. We don't merge undocumented components.

Testing

There's no full E2E suite yet — the SDK is small enough that visual review via Storybook and the showcase apps is sufficient. We're considering Playwright + visual regression once the storybook coverage is broader.

If you do add tests, place them next to the component (MyComponent.test.tsx) and prefer testing-library / RNTL over snapshots.

Code style

  • No comments unless explaining a non-obvious why. The component name + types should carry the what. If you need a comment, lead with // Why: ....

  • Strict TypeScript. No any, no as casts unless documented. forwardRef only on DOM-leaf components.

  • Functional components only. Hooks for state. No class components.

  • data-slot attribute on every custom component — it's how design-system tooling pin-points parts.

  • Tailwind utility classes only on web. No style={{}} for layout. Tokens for color.

Lessons-first

If you hit a non-trivial bug while developing, grep docs/lessons.md first. Several commonly-seen failure modes (Metro Unable to resolve "@otfdashkit/ui-native", dual-React crashes, tamagui peer-dep gotchas) have documented fixes. Use them, don't rebuild them. After fixing a non-trivial issue yourself, append a new lesson.

Release process

The SDK ships as scoped npm packages under the otfdashkit org:

We release together — one version, all packages. Currently at v0.1.0 (alpha). Breaking changes possible at minor versions until v1.0.0. Pin a specific version if that matters to you.

License

SDK packages are MIT. The kits are commercial under a separate license (see each kit's LICENSE-KIT.md). You can use the SDK in any project — commercial or non-commercial — without paying for a kit.