CLI
@objectifthunes/create-limestone is the official project scaffolder for Limestone SDK. It creates a fully configured Expo + Limestone app in seconds. The limestone CLI (installed alongside it) handles ongoing code generation tasks.
create-limestone
Usage
npx @objectifthunes/create-limestone my-app
That command starts an interactive prompt sequence. Answer the questions and a complete project is written to the my-app/ directory.
To skip prompts entirely and use a preset:
npx @objectifthunes/create-limestone my-app --yes --template full
npx @objectifthunes/create-limestone my-app --yes --template minimal
npx @objectifthunes/create-limestone my-app --yes --template prototype
--yes (or -y) accepts all defaults. --template (or -t) selects a preset. Both flags can be combined.
Interactive prompts
When running without --yes, the scaffolder asks:
| Prompt | Options | Default |
|---|---|---|
| Project name | Any valid npm package name | my-limestone-app |
| Theme | obsidian (dark), daylight (light), custom | obsidian |
| Configure API client | yes / no | yes |
| API base URL | Any URL | https://api.example.com |
| Adapters | Multi-select from 15 Expo adapters | all |
| Include dev adapter | yes / no | yes |
| Include tests | yes / no | yes |
| Navigation | expo-router, none | expo-router |
| Include example screens | yes / no | yes |
Presets
Three presets are available. Pass the name to --template or select it from the prompt.
full
All 15 Expo adapters wired up, Expo Router navigation, example tab screens, test setup, and the dev adapter included for local development.
npx @objectifthunes/create-limestone my-app --yes --template full
Includes: all adapters, expo-router, example screens, vitest test setup, dev adapter.
minimal
A clean starting point with no adapters, no navigation routing, and no example screens. Only the SDK core, theme, and provider are wired. Add what you need.
npx @objectifthunes/create-limestone my-app --yes --template minimal
Includes: SDK core only, no adapters, no example screens, dev adapter.
prototype
Everything from full, but every adapter is sourced from @objectifthunes/limestone-sdk/dev (in-memory doubles). No native modules to install. Runs in Expo Go and simulators out of the box. Tests are excluded because the intent is fast iteration, not coverage.
npx @objectifthunes/create-limestone my-app --yes --template prototype
Includes: all adapters (dev/in-memory), expo-router, example screens, no test setup.
Generated files
Every scaffold writes the following files regardless of preset:
my-app/
package.json # dependencies matching selected adapters
tsconfig.json
app.json # Expo config
.env.example # API_BASE_URL placeholder
.gitignore
CLAUDE.md # SDK quick reference for LLMs
limestone.config.ts # defineConfig() wired to selected adapters
app/_layout.tsx # LimestoneProvider root (expo-router)
app/index.tsx # Home screen
With example screens enabled (full / prototype):
app/(tabs)/_layout.tsx
app/(tabs)/index.tsx
app/(tabs)/settings.tsx
app/(tabs)/profile.tsx
With tests enabled (full):
__tests__/setup.ts
__tests__/example.test.ts
limestone add adapter
Wire an additional Expo adapter into an existing project.
limestone add adapter expo-biometrics
limestone add adapter expo-location
limestone add adapter expo-notifications
The command prints three steps:
- The
npx expo installcommand for the native module - The import to add to
limestone.config.ts - The
adaptersconfig key and factory call to add
Special adapters with no native install step:
limestone add adapter dev # All adapters as in-memory doubles
limestone add adapter testing # createTestApp() usage instructions
Available adapter names
| Name | Port | Native module |
|---|---|---|
expo-biometrics | BiometricProvider | expo-local-authentication |
expo-camera | CameraProvider | expo-camera |
expo-secure-store | SecureStorageProvider | expo-secure-store |
expo-haptics | HapticsProvider | expo-haptics |
expo-notifications | NotificationProvider | expo-notifications |
expo-purchases | PurchaseProvider | react-native-iap |
expo-permissions | PermissionsProvider | expo-modules-core |
expo-sharing | ShareProvider | expo-sharing |
expo-clipboard | ClipboardProvider | expo-clipboard |
expo-location | LocationProvider | expo-location |
expo-media-library | MediaLibraryProvider | expo-media-library |
expo-map | MapProvider | react-native-maps |
expo-web-browser | WebBrowserProvider | expo-web-browser |
expo-contacts | ContactsProvider | expo-contacts |
expo-review | ReviewProvider | expo-store-review |
dev | all ports (in-memory) | none |
testing | all ports (in-memory + state) | none |
limestone generate component
Scaffold a new headless component following the Limestone pattern: types.ts → use-<name>.ts → <name>.tsx → index.ts.
limestone generate component PriceCard
limestone generate component UserAvatar
limestone generate component CheckoutSummary
The name must be PascalCase. The scaffolder writes four files under components/<kebab-name>/:
components/price-card/
types.ts # PriceCardProps + UsePriceCardReturn interfaces
use-price-card.ts # Headless hook (no React dependency)
price-card.tsx # React Native component wired to useTheme()
index.ts # Barrel export
1. Run the generator
limestone generate component PriceCard2. Implement the headless hook
Open components/price-card/use-price-card.ts. Add your props to PriceCardProps, your return values to UsePriceCardReturn, and implement the logic. This file has no React dependency — keep it pure.
3. Render in the component
Open components/price-card/price-card.tsx. The hook is already wired to useTheme(). Replace the TODO comment with your JSX.
4. Import and use
import { PriceCard } from './components/price-card';