Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - kuraydev/react-native-typescript-library-starter: 🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box. · GitHub
Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - kuraydev/react-native-typescript-library-starter: 🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box. · GitHub
Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - kuraydev/react-native-typescript-library-starter: 🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box. · GitHub
Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - kuraydev/react-native-typescript-library-starter: 🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box. · GitHub
Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - kuraydev/react-native-typescript-library-starter: 🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box. · GitHub
Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - kuraydev/react-native-typescript-library-starter: 🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box. · GitHub
Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - kuraydev/react-native-typescript-library-starter: 🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box. · GitHub
Skip to content

Repository files navigation

📦 React Native TypeScript Library Starter

CInpm versionnpm downloadsLicense: MITPlatformTypeScript

A modern, production-ready starter for building React Native TypeScript libraries. Ships with dual CJS/ESM output, full test coverage, and AI-ready project conventions out of the box.


🆕 What's new in 3.0

  • Modern toolchain — React Native 0.87 / React 19 dev environment, TypeScript 5.9 with bundler module resolution
  • 🦀 oxlint + oxfmt — Rust-based linting and formatting replace ESLint + Prettier (lints the whole repo in milliseconds)
  • 📦 builder-bob 0.43 — ESM-enabled dual CJS/ESM output with per-condition type declarations and a spec-correct exports map
  • 🧪 RNTL v14 — tests migrated to the async render/renderHook API on the universal test renderer
  • 🧙 Interactive setup wizardnpm run setup configures name, author, repo URLs, license, and keywords in one pass
  • 🪝 Husky v9 — git hooks install automatically on npm install

See the full CHANGELOG for all changes including the 2.0.0 redesign.


🌟 Features

  • 📦 react-native-builder-bob — dual CJS + ESM output + per-condition TypeScript declarations
  • 🔒 Strict TypeScriptnoImplicitAny, strictNullChecks, noUnusedLocals
  • 🧪 Jest + @testing-library/react-native v14 — full async test suite with coverage thresholds
  • 🦀 oxlint + oxfmt — Rust-fast lint + format, enforced on commit via lint-staged
  • 🪝 Husky v9 + commitlint — conventional commits, hooks install on npm install
  • ⚙️ GitHub Actions — CI pipeline (typecheck + lint + format-check + test + build)
  • 🔁 Renovate — grouped weekly dependency updates
  • 🤖 AI-readyAGENTS.md conventions file for Claude Code, Cursor, Copilot & friends
  • AI-ReadyAGENTS.md, Cursor rules, and full TSDoc on every export
  • Interactive setup wizardnpm run setup to configure your library in 60 seconds
  • Example component and hook — reference implementations to clone from

🚀 Quick Start

1. Clone and install

git clone https://github.com/WrathChaos/react-native-typescript-library-starter.git my-library
cd my-library
npm install

2. Set up git hooks

Git hooks are installed automatically when you run npm install (via the prepare script). No extra step needed.

3. Configure the library

Run the interactive setup wizard. It walks through every field one by one, shows a preview of all planned changes, and asks for confirmation before writing anything:

npm run setup

The wizard will ask for:

  • Package name — your npm name (e.g. react-native-my-library)
  • Description — one sentence
  • GitHub username / org — used to build repo URLs automatically
  • GitHub repository name — defaults to your package name
  • Author name & email
  • License — MIT, Apache-2.0, ISC, GPL-3.0, or Unlicensed
  • Keywords — optional, comma-separated extras

After confirmation it updates package.json, README.md, AGENTS.md, and CONTRIBUTING.md in one go.

4. Replace the example code

The src/ folder contains a fully-typed example component and hook. Use them as reference, then replace with your own:

src/
├── components/MyComponent/ → replace with your component
├── hooks/useMyHook.ts → replace with your hook
└── index.ts → update exports

5. Build and verify

npm run build # outputs to lib/
npm run typecheck # type-check without emitting
npm test# run the test suite

📁 Project Structure

react-native-typescript-library-starter/
├── src/ # ALL source code
│ ├── index.ts # Public API entry point
│ ├── components/
│ │ └── MyComponent/
│ │ ├── MyComponent.tsx
│ │ ├── MyComponent.types.ts
│ │ └── index.ts
│ ├── hooks/
│ │ └── useMyHook.ts
│ ├── types/
│ │ └── index.ts
│ └── __tests__/
│ ├── MyComponent.test.tsx
│ └── useMyHook.test.ts
├── lib/ # Generated by bob (git-ignored)
├── .github/workflows/
│ ├── ci.yml # PR checks
│ └── release.yml # Publish pipeline
├── AGENTS.md # AI agent instructions
├── CONTRIBUTING.md
├── CHANGELOG.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
└── babel.config.js

🔧 Scripts

CommandDescription
npm run buildBuild library to lib/ via bob
npm run typecheckType-check without emitting
npm run lintRun oxlint with colored output and auto-fix
npm run lint:cioxlint without spinner (for CI)
npm run oxfmtFormat source files
npm run oxfmt:ciCheck formatting (for CI)
npm testRun Jest tests
npm run test:watchJest in watch mode
npm run test:coverageJest with coverage report

📦 Build Output

react-native-builder-bob produces three output targets inside lib/:

OutputPathUsed by
CommonJSlib/commonjs/Node.js, bundlers with require()
ESMlib/module/Modern bundlers, tree-shaking
TypeScriptlib/typescript/Type declarations for consumers

The package.jsonexports field routes consumers to the correct output automatically.


🧩 Example Component

import{MyComponent}from"your-library";exportdefaultfunctionApp(){return(<MyComponenttitle="Hello World"description="A fully-typed example component."enableButtonbuttonText="Tap me"onPress={()=>console.log("pressed")}/>);}

MyComponent Props

PropTypeDefaultDescription
titlestringPrimary title text (required)
descriptionstringOptional description below title
enableButtonbooleanfalseRenders an action button
buttonTextstring"Press me"Button label
onPress() => voidButton press callback
styleStyleProp<ViewStyle>Root container style override
titleStyleStyleProp<TextStyle>Title text style override
descriptionStyleStyleProp<TextStyle>Description text style override
buttonStyleStyleProp<ViewStyle>Button container style override
buttonTextStyleStyleProp<TextStyle>Button label style override
accessibilityLabelstringtitleAccessibility label for the container
testIDstring"my-component"Test ID for querying in tests

🪝 Example Hook

import{useMyHook}from"your-library";functionCounter(){const{ count, increment, decrement, reset, isAtMax, isAtMin }=useMyHook({initialValue: 0,max: 10,min: 0,step: 1,});return(<View><Text>{count}</Text><Buttontitle="+"onPress={increment}disabled={isAtMax}/><Buttontitle="-"onPress={decrement}disabled={isAtMin}/><Buttontitle="Reset"onPress={reset}/></View>);}

useMyHook Options

OptionTypeDefaultDescription
initialValuenumber0Starting counter value
maxnumberUpper bound (no limit if omitted)
minnumber0Lower bound
stepnumber1Increment/decrement amount

useMyHook Return

KeyTypeDescription
countnumberCurrent counter value
increment() => voidIncrement by step
decrement() => voidDecrement by step
reset() => voidReset to initialValue
isAtMaxbooleantrue when count >= max
isAtMinbooleantrue when count <= min

🧪 Testing

Tests use Jest and @testing-library/react-native.

npm test# run all tests
npm run test:coverage # with coverage report

Coverage thresholds are enforced in package.json:

  • Branches: 70%
  • Functions / Lines / Statements: 80%

📝 Commit Conventions

This project enforces Conventional Commits via commitlint:

feat: add MyButton component
fix: correct accessibility role
test: add boundary cases for useMyHook
docs: update README with new props
chore: upgrade dependencies

⚙️ CI

CI Pipeline (.github/workflows/ci.yml)

Runs on every push and pull request to main:

  1. Typechecktsc --noEmit
  2. Lint — oxlint + oxfmt check
  3. Test — Jest with coverage
  4. Buildbob build (only runs after all checks pass)

🤖 AI / LLM Usage

This starter is designed to be AI-friendly:

  • AGENTS.md — read this file first when working with an AI agent. It contains the full directory map, all runnable commands, conventions, naming rules, and do/don'ts.
  • .cursor/rules/library-conventions.mdc — Cursor AI rules that automatically enforce component/hook patterns.
  • TSDoc everywhere — every exported function, component, prop, and type has @param, @returns, and @example documentation. This maximises AI autocomplete quality.
  • Strict TypeScript — strict mode produces accurate types that AI tools can reason about reliably.
  • Conventional Commits — predictable commit history helps AI tools summarize changes and generate release notes.

Using with Cursor

The .cursor/rules/library-conventions.mdc rule is auto-applied to all src/**/*.ts and src/**/*.tsx files. It enforces component structure, hook patterns, and TSDoc requirements.

Using with Claude / ChatGPT

Paste the contents of AGENTS.md into the system prompt or the start of a conversation for best results.


🔗 Peer Dependencies

"peerDependencies": {
"react": ">=17.0.0",
"react-native": ">=0.70.0"
}

🤝 Contributing

See CONTRIBUTING.md for the full guide.


📜 Changelog

See CHANGELOG.md.


📄 License

MIT — see LICENSE.


👤 Author

kuraydevkurayogun@gmail.com
freakycoder.com

About

🚀 Production-ready starter for React Native TypeScript libraries — dual CJS/ESM output, strict types, full tests, automated releases, and AI-ready tooling out of the box.

Topics

Resources

Contributing

Stars

65 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages