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
| Kind | Where |
|---|---|
Bug in @otfdashkit/{ui, ui-native, tokens} | github.com/otf-kit/sdk/issues |
| Component request | Open a Discussion on the SDK repo with the use case + a sketch of the API |
| Docs typo / clarification | PR the relevant .mdx in apps/docs/content/ |
| Question | GitHub Discussions — we read everything |
| Bug in a paid kit | Email support after purchase; private kit repos have an issue tracker |
Local setup
git clone git@github.com:otf-kit/sdk.git
cd sdk
pnpm installThen pick what you're working on:
| Goal | Command |
|---|---|
| Storybook (web components) | pnpm --filter @otfdashkit/storybook-web dev |
| Storybook (native components) | pnpm --filter @otfdashkit/storybook-native dev |
| Native showcase app | pnpm --filter @otfdashkit/ui-native-showcase dev |
| Docs site | pnpm --filter @otfdashkit/docs dev |
| Build a single package | pnpm --filter @otfdashkit/<pkg> build |
| Type-check the whole repo | pnpm type-check |
| Lint the whole repo | pnpm lint |
Commit conventions
We use Conventional Commits:
feat(ui): add Marquee primitive— new featurefix(ui-native): centerBottomSheetsnap points— bug fixdocs: clarify token CSS load order— docs onlychore(deps): bump fumadocs-ui— choresrefactor(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
-
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.
-
Write Storybook stories before the component is final. Real usage flushes out API issues that look fine in isolation.
-
Follow the file convention.
kebab-case.tsxfilename,PascalCaseexported identifiers, single file per component (noindex.tsre-exports inside the component folder). -
Read tokens, don't redefine them. No hardcoded hex. No inline
style={{ background: ... }}.@otfdashkit/eslint-plugin-otf-designwill flag both. -
Test against the four shipped themes. A component that looks great in
theme-slatedark and breaks intheme-warmlight isn't done. -
Document on the same PR. Update the relevant
apps/docs/content/docs/components/.../*.mdxin 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, noascasts unless documented.forwardRefonly on DOM-leaf components. -
Functional components only. Hooks for state. No class components.
-
data-slotattribute 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.