Docs | Playground | DevTools
한국어 버전은 docs/README.ko.md를 확인해주세요.
Eliminate blank screens on revisits - Restore last state instantly
FirstTx elevates CSR app revisit experience to SSR-level:
- Prepaint: Instantly restore last screen before JS loads (0ms blank screen)
- Local-First: Auto-sync IndexedDB + React (data persists on refresh)
- Tx: Optimistic updates + auto-rollback (safe even on failure)
| Before | After |
![]() |
![]() |
| Slow 4G: Blank screen | Slow 4G: Instant restore |
See all demos in Playground
Traditional solutions for revisit UX (SSR/SSG) add infrastructure complexity. Manual IndexedDB requires 500+ lines of boilerplate. FirstTx provides SSR-level UX while keeping CSR architecture simple.
pnpm add @firsttx/prepaint @firsttx/local-first @firsttx/txPartial installation
- Revisit only:
pnpm add @firsttx/prepaint - Revisit + Sync:
pnpm add @firsttx/prepaint @firsttx/local-first - Sync + Tx:
pnpm add @firsttx/local-first @firsttx/tx
Tx requires Local-First as a dependency.
ESM-only. For CommonJS, use dynamic
import().
// vite.config.ts
import { firstTx } from '@firsttx/prepaint/plugin/vite';
export default defineConfig({
plugins: [firstTx()],
});// main.tsx
import { createFirstTxRoot } from '@firsttx/prepaint';
createFirstTxRoot(document.getElementById('root')!, <App />);import { useSyncedModel } from '@firsttx/local-first';
function CartPage() {
const { data: cart } = useSyncedModel(CartModel, () => fetch('/api/cart').then((r) => r.json()));
if (!cart) return <Skeleton />;
return <CartList items={cart.items} />;
}For optimistic updates with Tx, see API Reference.
| Use FirstTx | Consider Alternatives |
|---|---|
| Internal tools (CRM, dashboards) | Public landing pages → SSR/SSG |
| Frequent revisits (10+/day) | First-visit performance critical → SSR |
| No SEO requirements | Always need latest data → Server-driven UI |
| Browser | Min Version | ViewTransition |
|---|---|---|
| Chrome/Edge | 111+ | Full |
| Firefox | Latest | Graceful fallback |
| Safari | 16+ | Graceful fallback |
UI duplicates on refresh: Enable overlay: true in Vite plugin.
Hydration warnings: Add data-firsttx-volatile to frequently changing elements.
TypeScript errors: Add declare const __FIRSTTX_DEV__: boolean.
More at GitHub Issues.
MIT © joseph0926


