Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions src/components/landing/RedactLanding.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { Link } from '@tanstack/react-router'
import { CodeBlock } from '~/components/markdown/CodeBlock'
import {
LandingSection,
LandingSectionIntro,
LibraryLandingShell,
} from './LibraryLanding'

const repo = 'https://github.com/TanStack/redact'

export default function RedactLanding() {
return (
<LibraryLandingShell
libraryId="redact"
headline="React, redacted."
description="Keep your components, hooks, and React imports. Swap in a smaller runtime that renders synchronously, with one Vite plugin."
hero={
<div className="min-w-0 space-y-5">
<div
aria-label="React becomes Redact"
className="font-ds-display text-ds-heading-1 font-bold tracking-tight"
>
<span className="text-text-muted line-through decoration-[0.1em]">
React
</span>{' '}
Redact
</div>
<div className="grid grid-cols-2 gap-4">
<Link
to="/$libraryId/$version/docs/$"
params={{
libraryId: 'redact',
version: 'latest',
_splat: 'performance',
}}
className="rounded-xl border border-border-subtle bg-background-surface p-5 transition-opacity hover:opacity-80 sm:p-6"
>
<span className="block font-ds-display text-4xl font-bold sm:text-5xl">
66.3%
</span>
<span className="mt-2 block text-sm text-text-secondary">
smaller default runtime than React
</span>
</Link>
<Link
to="/$libraryId/$version/docs/$"
params={{
libraryId: 'redact',
version: 'latest',
_splat: 'feature-flags',
}}
className="rounded-xl border border-border-subtle bg-background-surface p-5 transition-opacity hover:opacity-80 sm:p-6"
>
<span className="block font-ds-display text-4xl font-bold sm:text-5xl">
12.5 <span className="text-xl">kB</span>
</span>
<span className="mt-2 block text-sm text-text-secondary">
nano DOM client, gzipped
</span>
</Link>
</div>
<p className="text-xs leading-relaxed text-text-secondary">
Redact 0.1.0 measurements. Savings compare all client exports with
React 19.3.0. Nano disables all optional features. App sizes vary.
</p>
<CodeBlock dataCodeTitle="vite.config.ts">
<code className="language-ts">{`import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { redact } from '@tanstack/redact/vite'

export default defineConfig({
plugins: [react(), redact()],
})`}</code>
</CodeBlock>
</div>
}
>
<LandingSection tone="accent">
<div className="grid items-center gap-10 lg:grid-cols-2 lg:gap-16">
<LandingSectionIntro
title="One plugin. Same imports."
body="Keep writing the React code you know. The Vite plugin handles React, React DOM, server rendering, scheduler, and JSX entrypoints for client and SSR builds."
/>
<CodeBlock dataCodeTitle="Counter.tsx">
<code className="language-tsx">{`import { useState } from 'react'

export function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
)
}`}</code>
</CodeBlock>
</div>
</LandingSection>
<LandingSection tone="raised">
<div className="grid items-center gap-10 lg:grid-cols-2 lg:gap-16">
<LandingSectionIntro
title="Only ship the parts you use."
body="Start with the default preset, then leave out behavior your app doesn't need. Or start with nano and turn features on individually, with explicit control over hydration, context, portals, Suspense, and more."
/>
<div className="min-w-0">
<CodeBlock dataCodeTitle="Feature selection">
<code className="language-ts">{`// A client-rendered app without class components
redact({
features: { hydration: false, classComponents: false },
})

// All optional features off, then context enabled
redact({ preset: 'nano', features: { context: true } })`}</code>
</CodeBlock>
<p className="mt-4 text-sm leading-relaxed text-text-secondary">
Disabling features changes behavior. Nano is not a
full-compatibility preset, and feature size savings are not
additive.
</p>
</div>
</div>
</LandingSection>
<LandingSection tone="ink">
<div className="grid gap-10 lg:grid-cols-2 lg:gap-16">
<LandingSectionIntro
title="Know what changes."
body="Redact keeps the React component model without concurrent scheduling. Rendering and transitions run synchronously, pending stays false, and deferred values return their input. Actions and optimistic state have limited behavior."
/>
<div className="space-y-5 text-ds-body-sm leading-relaxed text-text-secondary">
<p>
Streaming SSR, hydration, Suspense, and Fast Refresh are
supported. Server Components stay on upstream React in the RSC
environment. React DevTools inspection is not implemented.
</p>
<Link
to="/$libraryId/$version/docs/$"
params={{
libraryId: 'redact',
version: 'latest',
_splat: 'compatibility',
}}
className="inline-block font-medium text-text-primary underline underline-offset-4"
>
Read the compatibility guide
</Link>
<p>
Performance depends on the workload. Published measurements
include faster state updates and slower hydration and Suspense
retries, they do not establish whole-app speedups.
</p>
<a
href={`${repo}/blob/main/benchmarks/SHIP_MEASUREMENTS.md`}
className="inline-block font-medium text-text-primary underline underline-offset-4"
>
Performance measurements ↗
</a>
</div>
</div>
</LandingSection>
</LibraryLandingShell>
)
}
1 change: 1 addition & 0 deletions src/libraries/categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type LibraryCategory =
export const libraryCategories: Record<string, LibraryCategory> = {
start: 'framework',
router: 'framework',
redact: 'framework',
query: 'data',
db: 'data',
store: 'data',
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/icons.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EraserIcon } from '@phosphor-icons/react/Eraser'
import { BrainIcon } from '@phosphor-icons/react/Brain'
import { ChartLineUpIcon } from '@phosphor-icons/react/ChartLineUp'
import { ClipboardTextIcon } from '@phosphor-icons/react/ClipboardText'
Expand Down Expand Up @@ -29,6 +30,7 @@ import type { Icon } from '@phosphor-icons/react'
export const libraryIcons: Record<string, Icon> = {
start: SunHorizonIcon,
router: TrafficSignIcon,
redact: EraserIcon,
query: SealQuestionIcon,
db: DatabaseIcon,
store: DresserIcon,
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/ids.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const libraryIds = [
'start',
'router',
'redact',
'query',
'table',
'charts',
Expand Down Expand Up @@ -29,6 +30,7 @@ export type LibraryId = (typeof libraryIds)[number]
export const SIDEBAR_LIBRARY_IDS = [
'start',
'router',
'redact',
'query',
'table',
'db',
Expand Down
1 change: 1 addition & 0 deletions src/libraries/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export {
hotkeys,
markdown,
highlight,
redact,
db,
ai,
intent,
Expand Down
26 changes: 25 additions & 1 deletion src/libraries/libraries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,29 @@ export const highlight: LibrarySlim = {
},
}

export const redact: LibrarySlim = {
id: 'redact',
scarfId: 'c8168526-db90-4e35-9eaf-bb22ac7c7d18',
...categoryStyles.framework,
name: 'TanStack Redact',
to: '/redact/latest',
tagline: 'A smaller React-compatible runtime with synchronous rendering',
description:
'Keep your React components, hooks, and imports, with a smaller synchronous runtime, a Vite plugin, and optional features you can leave out of your bundle.',
repo: 'tanstack/redact',
frameworks: ['react'],
frameworkPackageNames: { react: '@tanstack/redact' },
frameworkDocs: { react: 'overview' },
corePackageName: '@tanstack/redact',
npmPackageNames: ['@tanstack/redact'],
latestVersion: 'v0',
latestBranch: 'main',
availableVersions: ['v0'],
defaultDocs: 'overview',
installPath: 'installation',
sitemap: { includeLandingPage: true, includeDocsPages: true },
}

export const db: LibrarySlim = {
id: 'db',
...categoryStyles.data,
Expand Down Expand Up @@ -930,6 +953,7 @@ export const libraries: LibrarySlim[] = [
hotkeys,
markdown,
highlight,
redact,
store,
ranger,
config,
Expand Down Expand Up @@ -980,7 +1004,7 @@ export function isPublicLibrary(
export const publicLibraries = libraries.filter(isPublicLibrary)

export const librariesByGroup = {
framework: [start, router],
framework: [start, router, redact],
state: [query, db, store, ai],
headlessUI: [table, charts, form, hotkeys, markdown, highlight],
performance: [virtual, pacer],
Expand Down
Loading
Loading