Skip to content

Commit 1fa8157

Browse files
committed
Merge branch 'cursor/merge-branch-into-main-3992'
2 parents 5f3a4e8 + 11edb78 commit 1fa8157

File tree

4 files changed

+281
-62
lines changed

4 files changed

+281
-62
lines changed

docs-site/docusaurus.config.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ const config = {
5353
],
5454
],
5555

56+
plugins: [
57+
[
58+
require.resolve('@easyops-cn/docusaurus-search-local'),
59+
{
60+
hashed: true,
61+
highlightSearchTermsOnTargetPage: true,
62+
docsRouteBasePath: '/docs',
63+
indexBlog: false,
64+
language: ['en'],
65+
},
66+
],
67+
],
68+
5669
themeConfig:
5770
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
5871
({
@@ -82,6 +95,10 @@ const config = {
8295
label: 'npm',
8396
position: 'right',
8497
},
98+
{
99+
type: 'search',
100+
position: 'right',
101+
},
85102
],
86103
},
87104
footer: {

docs-site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@docusaurus/core": "^3.9.2",
1818
"@docusaurus/preset-classic": "^3.9.2",
1919
"@mdx-js/react": "^3.1.1",
20+
"@easyops-cn/docusaurus-search-local": "^0.44.0",
2021
"clsx": "^2.1.1",
2122
"prism-react-renderer": "^2.4.1",
2223
"react": "^18.3.1",

docs-site/src/pages/index.js

Lines changed: 161 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,123 @@ import Layout from '@theme/Layout';
33
import Link from '@docusaurus/Link';
44
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
55
import useBaseUrl from '@docusaurus/useBaseUrl';
6+
import {useColorMode} from '@docusaurus/theme-common';
67
import clsx from 'clsx';
78
import styles from './index.module.css';
89

9-
const features = [
10+
const pillars = [
1011
{
1112
icon: '🛡️',
12-
title: 'Resilient Middleware',
13+
title: 'Crash guard for every handler',
1314
description:
14-
'Prevent crashes across every Express route with a zero-dependency runtime guard that isolates failures and keeps traffic flowing.',
15+
'Automatically wraps Express routes so unhandled sync or async errors resolve to consistent JSON responses instead of crashing the process.',
1516
},
1617
{
17-
icon: '📊',
18-
title: 'Built-in Observability',
18+
icon: '📈',
19+
title: 'Dashboards without agents',
1920
description:
20-
'Ship production dashboards, traces, and metrics out of the box—no vendor lock-in, agents, or sidecars required.',
21+
'Ship the built-in Crashless UI at `/_crashless` for live throughput, percentile latency, and error analytics—no vendor lock-in or sidecars.',
2122
},
2223
{
23-
icon: '⚙️',
24-
title: 'Optimized for Node.js',
24+
icon: '🧭',
25+
title: 'Trace-first instrumentation',
2526
description:
26-
'Crafted specifically for Node.js APIs with <5ms overhead per request and native support for async/await workflows.',
27+
'AsyncLocalStorage-powered tracing, fetch/fs auto-patching, and OTLP exports come ready to toggle on when you want deep visibility.',
28+
},
29+
{
30+
icon: '🔐',
31+
title: 'Production-safe by default',
32+
description:
33+
'Mask sensitive payloads, gate dashboards with token or IP checks, and stream metrics securely with zero runtime npm dependencies.',
2734
},
2835
];
2936

3037
const highlights = [
31-
{value: '<5ms', label: 'Median request overhead'},
32-
{value: '99.99%', label: 'Crash-free uptime with guards enabled'},
33-
{value: '60s', label: 'Time to first dashboard'},
34-
{value: '0', label: 'Third-party dependencies required'},
38+
{value: '1', label: 'line to enable crash prevention'},
39+
{value: '+2.3%', label: 'overhead in minimal guard mode'},
40+
{value: '60s', label: 'to first dashboard at /_crashless'},
41+
{value: '0', label: 'runtime npm dependencies'},
3542
];
3643

37-
const rollouts = [
44+
const playbook = [
45+
{
46+
title: 'Drop the middleware in',
47+
description:
48+
'Add crashless() to your Express app and keep every existing handler—async patching and error normalization happen automatically.',
49+
},
3850
{
39-
title: 'Drop-in install',
51+
title: 'Open the live console',
4052
description:
41-
'Add the Crashless middleware to any existing Express app with a single import and immediate protection.',
53+
'Visit the built-in dashboard for request metrics, latency percentiles, and crash analytics powered by the in-memory registry.',
4254
},
4355
{
44-
title: 'Instrument automatically',
56+
title: 'Tune telemetry intentionally',
4557
description:
46-
'Capture traces, metrics, and alerts without touching your handlers—Crashless hooks into core Node.js primitives.',
58+
'Follow the docs to flip between minimal guards, built-in metrics, or trace sampling depending on the environment you’re deploying.',
4759
},
4860
{
49-
title: 'Operate with confidence',
61+
title: 'Export when you need to share',
5062
description:
51-
'Unified dashboards highlight hotspots, slow transactions, and error bursts so you can resolve issues before users notice.',
63+
'Expose Prometheus and OTLP endpoints out-of-the-box so Grafana, Datadog, or OpenTelemetry collectors can ingest your data.',
64+
},
65+
];
66+
67+
const docsSpotlight = [
68+
{
69+
title: 'Getting Started',
70+
description: 'Install in one minute, protect routes instantly, and access the dashboard locally.',
71+
to: '/docs/getting-started',
72+
badge: 'Start here',
73+
},
74+
{
75+
title: 'Configuration',
76+
description: 'Dial in telemetry engines, security, sampling, and dashboard access for every stage.',
77+
to: '/docs/configuration',
78+
badge: 'Tweak settings',
79+
},
80+
{
81+
title: 'Architecture',
82+
description: 'Learn how zero-dependency middleware, AsyncLocalStorage, and the metrics registry work together.',
83+
to: '/docs/architecture',
84+
badge: 'Under the hood',
85+
},
86+
{
87+
title: 'Examples',
88+
description: 'Copy production-ready patterns for exporters, dashboards, tracing, and rollout strategies.',
89+
to: '/docs/examples',
90+
badge: 'Copy & paste',
5291
},
5392
];
5493

55-
const codeExample = `import crashless from 'crashless';
94+
const codeExample = `import express from 'express';
95+
import crashless from 'crashless';
96+
97+
const app = express();
5698
5799
app.use(
58100
crashless({
59-
dashboards: true,
60-
tracing: { sampler: { probability: 0.1 } },
101+
appName: 'Checkout API',
102+
telemetry: {
103+
engine: 'builtin',
104+
dashboard: true,
105+
traces: { enabled: true, samplingRate: 0.2 },
106+
},
107+
enableDashboard: true,
108+
dashboardAuth: req => req.ip === '127.0.0.1',
61109
}),
62110
);
63111
64-
app.get('/checkout', crashless.route(async (req, res) => {
65-
const result = await runBusinessLogic(req.body);
66-
res.json(result);
67-
}));
112+
app.get('/checkout', async (req, res) => {
113+
const order = await placeOrder(req.body);
68114
69-
await crashless.start();`;
115+
if (!order.ok) {
116+
throw crashless.createError('Payment declined', 402, 'ERR_PAYMENT');
117+
}
118+
119+
res.json(order.data);
120+
});
121+
122+
app.listen(3000);`;
70123

71124
function FeatureCard({icon, title, description}) {
72125
return (
@@ -96,64 +149,77 @@ function RolloutStep({title, description}) {
96149
);
97150
}
98151

152+
function DocCard({title, description, to, badge}) {
153+
return (
154+
<Link to={to} className={styles.docsCard}>
155+
<span className={styles.docsBadge}>{badge}</span>
156+
<h3>{title}</h3>
157+
<p>{description}</p>
158+
<span className={styles.docsArrow}>Read the guide →</span>
159+
</Link>
160+
);
161+
}
162+
99163
export default function Home() {
100164
const {siteConfig} = useDocusaurusContext();
101165
const heroImageUrl = useBaseUrl('img/banner.png');
166+
const {colorMode} = useColorMode();
167+
const stackblitzTheme = colorMode === 'dark' ? 'dark' : 'light';
168+
const stackblitzUrl =
169+
'https://stackblitz.com/github/sunnyghodeswar/crashless-examples?file=examples%2Fexample-one-liner.js&embed=1&hideExplorer=1&hideNavigation=1&view=preview';
170+
const stackblitzSrc = `${stackblitzUrl}&theme=${stackblitzTheme}`;
102171

103172
return (
104173
<Layout
105174
title={siteConfig.title}
106-
description="Crashless delivers production-grade observability and crash prevention for Node.js APIs with zero extra dependencies.">
175+
description="Crashless delivers crash prevention, distributed tracing, and live dashboards for Node.js APIs without adding dependencies.">
107176
<main className={styles.main}>
108177
<section className={styles.hero}>
109178
<div className={styles.heroContent}>
110-
<span className={styles.heroBadge}>Observability built for Node.js</span>
111-
<h1 className={styles.heroTitle}>Crashless</h1>
112-
<p className={styles.heroSubtitle}>
113-
Production-ready crash prevention and monitoring without agents, vendors, or friction.
114-
</p>
179+
<span className={styles.heroBadge}>Zero-dependency observability</span>
180+
<h1 className={styles.heroTitle}>Crashless keeps your Node.js APIs online</h1>
181+
<p className={styles.heroSubtitle}>Stop production crashes from stray async errors and unlock dashboards in seconds.</p>
115182
<p className={styles.heroDescription}>
116-
Harden your Express apps with protective middleware, real-time dashboards, actionable alerts, and full-stack traces—all activated in minutes.
183+
Wrap Express once to enforce consistent error handling, stream rich telemetry, and export traces—all while staying in
184+
control of overhead.
117185
</p>
118186
<div className={styles.heroActions}>
119187
<Link className={clsx('button button--primary button--lg', styles.primaryButton)} to="/docs/getting-started">
120-
Start in 60 seconds
188+
Install in one minute
121189
</Link>
122190
<Link className="button button--outline button--lg" to="/docs/architecture">
123191
Explore the architecture
124192
</Link>
125193
</div>
126-
<div className={styles.heroFootnote}>Zero agents. Zero downtime during rollout.</div>
194+
<div className={styles.heroFootnote}>MIT licensed • Works with Express 4 & 5 Node.js 18+</div>
127195
</div>
128196
<div className={styles.heroMedia}>
129197
<img src={heroImageUrl} alt="Crashless dashboard preview" className={styles.heroImage} loading="lazy" />
130198
<div className={styles.heroCallout}>
131-
<span className={styles.heroCalloutLabel}>Live insights</span>
132-
<p>Automatic anomaly detection, latency breakdowns, and error analytics without extra wiring.</p>
199+
<span className={styles.heroCalloutLabel}>Telemetry included</span>
200+
<p>Percentile latency, crash analytics, Prometheus exports, and AsyncLocalStorage traces with zero extra services.</p>
133201
</div>
134202
</div>
135203
</section>
136204

137205
<section className={styles.trustStrip}>
138-
<p className={styles.trustLabel}>Trusted by teams delivering high-availability Node.js services</p>
206+
<p className={styles.trustLabel}>Everything teams need in one guardrail-first package</p>
139207
<div className={styles.trustTags}>
140-
<span>Fintech</span>
141-
<span>SaaS</span>
142-
<span>E-commerce</span>
143-
<span>Media</span>
208+
<span>Async error shields</span>
209+
<span>Built-in dashboards</span>
210+
<span>Prometheus & OTLP</span>
211+
<span>Token/IP gating</span>
144212
</div>
145213
</section>
146214

147215
<section className={styles.featureSection}>
148216
<div className={styles.sectionHeader}>
149217
<span className={styles.sectionBadge}>Why Crashless</span>
150-
<h2>Everything you need to keep APIs resilient</h2>
151-
<p>
152-
Crashless combines defensive middleware with observability guardrails so teams can focus on product, not plumbing.
153-
</p>
218+
<h2>All-in-one resilience for Node.js APIs</h2>
219+
<p>Crashless merges crash prevention, observability, and secure operations into a single install so you can focus on shipping product.</p>
154220
</div>
155221
<div className={styles.featureGrid}>
156-
{features.map(feature => (
222+
{pillars.map(feature => (
157223
<FeatureCard key={feature.title} {...feature} />
158224
))}
159225
</div>
@@ -168,30 +234,66 @@ export default function Home() {
168234
<section className={styles.rolloutSection}>
169235
<div className={styles.sectionHeader}>
170236
<span className={styles.sectionBadge}>Rollout playbook</span>
171-
<h2>Upgrade observability without rewriting your stack</h2>
172-
<p>Follow a clear path from installation to insight, backed by automation at every step.</p>
237+
<h2>Go from install to insight without rewrites</h2>
238+
<p>Follow the adoption path outlined in the docs: start with guards, then layer in dashboards, metrics, and traces as you need them.</p>
173239
</div>
174240
<div className={styles.rolloutGrid}>
175-
{rollouts.map(step => (
241+
{playbook.map(step => (
176242
<RolloutStep key={step.title} {...step} />
177243
))}
178244
</div>
179245
</section>
180246

247+
<section className={styles.docsSection}>
248+
<div className={styles.sectionHeader}>
249+
<span className={styles.sectionBadge}>Docs that go deep</span>
250+
<h2>Everything documented, from hello world to internals</h2>
251+
<p>Dive into the guides to configure telemetry, understand the architecture, and copy production-ready patterns straight into your app.</p>
252+
</div>
253+
<div className={styles.docsGrid}>
254+
{docsSpotlight.map(doc => (
255+
<DocCard key={doc.title} {...doc} />
256+
))}
257+
</div>
258+
</section>
259+
260+
<section className={styles.playgroundSection}>
261+
<div className={styles.sectionHeader}>
262+
<span className={styles.sectionBadge}>Try it live</span>
263+
<h2>Experiment with Crashless in your browser</h2>
264+
<p>Spin up the StackBlitz demo to explore middleware guards, dashboards, and tracing without leaving the docs.</p>
265+
</div>
266+
<div className={styles.playgroundFrameWrapper}>
267+
<iframe
268+
src={stackblitzSrc}
269+
title="Crashless StackBlitz Demo"
270+
loading="lazy"
271+
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
272+
allowFullScreen
273+
/>
274+
</div>
275+
<div className={styles.playgroundFooter}>
276+
<span>Prefer a full tab?</span>
277+
<Link to={stackblitzUrl} className="button button--link">
278+
Open StackBlitz demo →
279+
</Link>
280+
</div>
281+
</section>
282+
181283
<section className={styles.codeSection}>
182284
<div className={styles.sectionHeader}>
183285
<span className={styles.sectionBadge}>See how it works</span>
184-
<h2>Instrument your Express app in minutes</h2>
185-
<p>Crashless wraps your existing routes to guarantee reliability while streaming telemetry to your dashboard.</p>
286+
<h2>Protect handlers and surface telemetry with one import</h2>
287+
<p>Crashless instruments Express while letting you choose how much observability to enable for each environment.</p>
186288
</div>
187289
<div className={styles.codeBlock}>
188290
<pre>
189291
<code>{codeExample}</code>
190292
</pre>
191293
</div>
192294
<div className={styles.codeActions}>
193-
<Link className="button button--link" to="/docs/api-reference">
194-
View the full API reference
295+
<Link className="button button--link" to="/docs/configuration">
296+
Review configuration options
195297
</Link>
196298
<Link className="button button--link" to="/docs/examples">
197299
Browse production-ready examples →
@@ -201,13 +303,11 @@ export default function Home() {
201303

202304
<section className={styles.ctaSection}>
203305
<div className={styles.ctaCard}>
204-
<h2>Ship reliable Node.js services faster</h2>
205-
<p>
206-
Join teams that ship resilient APIs with instant crash protection, best-in-class observability, and zero operational overhead.
207-
</p>
306+
<h2>Ship resilient Node.js services without the overhead</h2>
307+
<p>Deploy Crashless to stay crash-free, watch live metrics, and export telemetry to your existing observability stack whenever you need it.</p>
208308
<div className={styles.heroActions}>
209309
<Link className={clsx('button button--primary button--lg', styles.primaryButton)} to="/docs/getting-started">
210-
Get started
310+
Start in 60 seconds
211311
</Link>
212312
<Link className="button button--secondary button--lg" to="/docs/performance">
213313
See performance benchmarks

0 commit comments

Comments
 (0)