Basic Usage
After running bunx readonly sync, your files are available for import:
import { documents , config , redirects } from "@readonlystore/client" ;
console . log ( documents . title );
console . log ( config . apiUrl );
console . log ( redirects [ "/old-path" ]);
All imports are fully typed with IntelliSense support!
Type Safety
ReadOnly automatically generates TypeScript types by introspecting your JSON files.
Example
Given this JSON file named config:
{
"apiUrl" : "https://api.example.com" ,
"timeout" : 5000 ,
"retries" : 3 ,
"features" : {
"darkMode" : true ,
"analytics" : false
},
"endpoints" : [ "/users" , "/posts" , "/comments" ]
}
ReadOnly generates this type:
export declare const config : {
apiUrl : string ;
timeout : number ;
retries : number ;
features : {
darkMode : boolean ;
analytics : boolean ;
};
endpoints : string [];
};
IntelliSense
Your editor will provide:
Auto-completion for all properties
Type checking
Inline documentation
Go-to-definition support
Import Patterns
Named Imports
Import specific files:
import { documents } from "@readonlystore/client" ;
import { config } from "@readonlystore/client" ;
import { redirects } from "@readonlystore/client" ;
Wildcard Import
Import all files at once:
import * as readonly from "@readonlystore/client" ;
console . log ( readonly . documents );
console . log ( readonly . config );
Re-exporting
Re-export for use throughout your app:
// lib/readonly.ts
export { documents , config , redirects } from "@readonlystore/client" ;
// elsewhere in your app
import { documents } from "@/lib/readonly" ;
Common Use Cases
1. Configuration
Store app configuration in ReadOnly:
import { config } from "@readonlystore/client" ;
const api = axios . create ({
baseURL: config . apiUrl ,
timeout: config . timeout ,
});
2. Content Management
Manage blog posts or documentation:
import { posts } from "@readonlystore/client" ;
export function BlogList () {
return (
< div >
{ posts . items . map ( post => (
< article key = {post. id } >
< h2 >{post. title } </ h2 >
< p >{post. excerpt } </ p >
</ article >
))}
</ div >
);
}
3. Redirects
Handle URL redirects:
import { redirects } from "@readonlystore/client" ;
export function middleware ( request : Request ) {
const path = new URL ( request . url ). pathname ;
const redirect = redirects [ path ];
if ( redirect ) {
return Response . redirect ( redirect , 301 );
}
}
4. Feature Flags
Manage feature flags:
import { features } from "@readonlystore/client" ;
export function App () {
return (
< div >
{ features . darkMode && < DarkModeToggle />}
{ features . analytics && < Analytics />}
</ div >
);
}
5. Reference Data
Store reference data like countries, currencies, etc:
import { countries } from "@readonlystore/client" ;
export function CountrySelect () {
return (
< select >
{ countries . map ( country => (
< option key = {country. code } value = {country. code } >
{ country . name }
</ option >
))}
</ select >
);
}
Framework Examples
Next.js
// app/page.tsx
import { documents } from "@readonlystore/client" ;
export default function Home () {
return (
< div >
< h1 >{documents. title } </ h1 >
< p >{documents. description } </ p >
</ div >
);
}
Express
// server.ts
import express from "express" ;
import { config } from "@readonlystore/client" ;
const app = express ();
app . listen ( config . port , () => {
console . log ( `Server running on port ${ config . port } ` );
});
Remix
// app/routes/_index.tsx
import { json } from "@remix-run/node" ;
import { useLoaderData } from "@remix-run/react" ;
import { documents } from "@readonlystore/client" ;
export const loader = () => {
return json ({ documents });
};
export default function Index () {
const { documents } = useLoaderData < typeof loader >();
return < h1 >{documents. title } </ h1 > ;
}
Astro
---
// src/pages/index.astro
import { documents } from "@readonlystore/client" ;
---
< html >
< body >
< h1 > { documents . title } </ h1 >
< p > { documents . description } </ p >
</ body >
</ html >
Runtime vs Build Time
Runtime Loading
Files are loaded at runtime from the cache:
// This loads from node_modules/.cache/readonly/documents.json
import { documents } from "@readonlystore/client" ;
Build Time Sync
Sync during build to include files in your bundle:
{
"scripts" : {
"build" : "readonly sync && next build"
}
}
File Updates
Development
Use watch mode to automatically sync updates:
When you update files in the dashboard, they’ll sync automatically.
Production
Run watch mode alongside your app:
{
"scripts" : {
"start" : "concurrently \" node server.js \" \" readonly dev \" "
}
}
Best Practices
Individual files are limited to 10MB. Keep files focused and avoid large datasets.
Name your files descriptively: config, features, redirects, not data1, file2.
Ensure your JSON is valid and follows a consistent structure. ReadOnly validates JSON objects only (no arrays or
primitives at root).
Always run readonly sync before building for production to ensure files are up-to-date.
Use watch mode in development
Run readonly dev alongside your dev server to automatically sync changes.
Next Steps
CLI Reference Learn about all available commands.
Configuration Customize cache and output directories.
Installation Installation and setup guide.
Troubleshooting Common issues and solutions.