create-fumadocs-app 15.6.3 → 15.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/chunk-J4NXLHNR.js +330 -0
  2. package/dist/create-app.d.ts +5 -3
  3. package/dist/create-app.js +5 -3
  4. package/dist/index.js +84 -38
  5. package/package.json +5 -4
  6. package/template/react-router/app/docs/page.tsx +4 -8
  7. package/template/react-router/app/routes/home.tsx +2 -3
  8. package/template/react-router/content/docs/test.mdx +20 -4
  9. package/template/react-router/package.json +35 -0
  10. package/template/tanstack-start/content/{docs/index.mdx → index.mdx} +2 -3
  11. package/template/tanstack-start/content/test.mdx +10 -0
  12. package/template/tanstack-start/example.gitignore +8 -2
  13. package/template/tanstack-start/package.json +35 -0
  14. package/template/tanstack-start/src/components/NotFound.tsx +28 -0
  15. package/template/tanstack-start/{lib → src/lib}/source.ts +17 -21
  16. package/template/tanstack-start/{app → src}/router.tsx +3 -0
  17. package/template/tanstack-start/{app → src}/routes/__root.tsx +4 -3
  18. package/template/tanstack-start/{app → src}/routes/api/search.ts +5 -8
  19. package/template/tanstack-start/{app → src}/routes/docs/$.tsx +47 -18
  20. package/template/tanstack-start/{app → src}/routes/index.tsx +4 -1
  21. package/template/tanstack-start/tsconfig.json +14 -7
  22. package/template/tanstack-start/vite.config.ts +21 -0
  23. package/dist/chunk-FAFA6275.js +0 -380
  24. package/template/tanstack-start/app/api.ts +0 -6
  25. package/template/tanstack-start/app/client.tsx +0 -7
  26. package/template/tanstack-start/app/ssr.tsx +0 -13
  27. package/template/tanstack-start/app.config.ts +0 -43
  28. /package/template/tanstack-start/{app → src/styles}/app.css +0 -0
@@ -0,0 +1,330 @@
1
+ // src/create-app.ts
2
+ import path from "path";
3
+ import fs2 from "fs/promises";
4
+
5
+ // src/git.ts
6
+ import * as fs from "fs/promises";
7
+ import { join } from "path";
8
+ import { x } from "tinyexec";
9
+ async function isInGitRepository(cwd2) {
10
+ const { exitCode } = await x("git", ["rev-parse", "--is-inside-work-tree"], {
11
+ nodeOptions: { cwd: cwd2 }
12
+ });
13
+ return exitCode !== 0;
14
+ }
15
+ async function isDefaultBranchSet(cwd2) {
16
+ const { exitCode } = await x("git", ["config", "init.defaultBranch"], {
17
+ nodeOptions: { cwd: cwd2 }
18
+ });
19
+ return exitCode !== 0;
20
+ }
21
+ async function tryGitInit(cwd2) {
22
+ const { exitCode } = await x("git", ["--version"]);
23
+ if (exitCode !== 0) return false;
24
+ if (await isInGitRepository(cwd2)) return false;
25
+ try {
26
+ await x("git", ["init"], {
27
+ throwOnError: true,
28
+ nodeOptions: { cwd: cwd2 }
29
+ });
30
+ if (!await isDefaultBranchSet(cwd2)) {
31
+ await x("git", ["checkout", "-b", "main"], {
32
+ throwOnError: true,
33
+ nodeOptions: {
34
+ cwd: cwd2
35
+ }
36
+ });
37
+ }
38
+ await x("git", ["add", "-A"], {
39
+ throwOnError: true,
40
+ nodeOptions: {
41
+ cwd: cwd2
42
+ }
43
+ });
44
+ await x(
45
+ "git",
46
+ ["commit", "-m", "Initial commit from Create Fumadocs App"],
47
+ {
48
+ throwOnError: true,
49
+ nodeOptions: {
50
+ cwd: cwd2
51
+ }
52
+ }
53
+ );
54
+ return true;
55
+ } catch {
56
+ await fs.rmdir(join(cwd2, ".git"), { recursive: true }).catch(() => null);
57
+ return false;
58
+ }
59
+ }
60
+
61
+ // src/versions.js
62
+ var versions = { "fumadocs-core": "15.6.5", "fumadocs-ui": "15.6.5", "fumadocs-mdx": "11.7.0", "@fumadocs/mdx-remote": "1.4.0", "@fumadocs/content-collections": "1.2.1" };
63
+
64
+ // ../create-app-versions/package.json
65
+ var package_default = {
66
+ name: "example-versions",
67
+ version: "0.0.0",
68
+ private: true,
69
+ description: "Used to track dependency versions in create-fumadocs-app",
70
+ license: "MIT",
71
+ dependencies: {
72
+ "@content-collections/core": "^0.10.0",
73
+ "@content-collections/mdx": "^0.2.2",
74
+ "@content-collections/next": "^0.2.6",
75
+ "@react-router/dev": "^7.7.0",
76
+ "@react-router/node": "^7.7.0",
77
+ "@react-router/serve": "^7.7.0",
78
+ "@tailwindcss/postcss": "^4.1.11",
79
+ "@tailwindcss/vite": "^4.1.11",
80
+ "@tanstack/react-router": "^1.128.8",
81
+ "@tanstack/react-start": "^1.128.8",
82
+ "@types/mdx": "^2.0.13",
83
+ "@types/node": "24.0.15",
84
+ "@types/react": "^19.1.8",
85
+ "@types/react-dom": "^19.1.6",
86
+ "@vitejs/plugin-react": "^4.7.0",
87
+ "gray-matter": "^4.0.3",
88
+ isbot: "^5.1.28",
89
+ next: "15.4.2",
90
+ postcss: "^8.5.6",
91
+ react: "^19.1.0",
92
+ "react-dom": "^19.1.0",
93
+ "react-router": "^7.7.0",
94
+ "react-router-devtools": "^5.0.6",
95
+ shiki: "^3.8.1",
96
+ tailwindcss: "^4.1.11",
97
+ tinyglobby: "^0.2.14",
98
+ typescript: "^5.8.3",
99
+ vinxi: "^0.5.8",
100
+ vite: "^7.0.5",
101
+ "vite-tsconfig-paths": "^5.1.4"
102
+ }
103
+ };
104
+
105
+ // src/auto-install.ts
106
+ import { x as x2 } from "tinyexec";
107
+ var managers = ["npm", "yarn", "bun", "pnpm"];
108
+ function getPackageManager() {
109
+ const userAgent = process.env.npm_config_user_agent ?? "";
110
+ if (userAgent.startsWith("yarn")) {
111
+ return "yarn";
112
+ }
113
+ if (userAgent.startsWith("pnpm")) {
114
+ return "pnpm";
115
+ }
116
+ if (userAgent.startsWith("bun")) {
117
+ return "bun";
118
+ }
119
+ return "npm";
120
+ }
121
+ async function autoInstall(manager, dest) {
122
+ await x2(manager, ["install"], {
123
+ throwOnError: true,
124
+ nodeOptions: {
125
+ env: {
126
+ ...process.env,
127
+ NODE_ENV: "development",
128
+ DISABLE_OPENCOLLECTIVE: "1"
129
+ },
130
+ cwd: dest
131
+ }
132
+ });
133
+ }
134
+
135
+ // src/constants.ts
136
+ import { fileURLToPath } from "url";
137
+ var sourceDir = fileURLToPath(new URL(`../`, import.meta.url).href);
138
+ var cwd = process.cwd();
139
+
140
+ // src/create-app.ts
141
+ var templates = [
142
+ "+next+content-collections",
143
+ "+next+fuma-docs-mdx",
144
+ "react-router",
145
+ "tanstack-start"
146
+ ];
147
+ async function create(options) {
148
+ const {
149
+ installDeps = true,
150
+ initializeGit = true,
151
+ log = console.log
152
+ } = options;
153
+ const projectName = path.basename(options.outputDir);
154
+ const dest = path.resolve(cwd, options.outputDir);
155
+ const isNext = options.template.startsWith("+next");
156
+ function isRelative(dir, file) {
157
+ return !path.relative(path.join(dest, dir), file).startsWith(`..${path.sep}`);
158
+ }
159
+ function defaultRename(file) {
160
+ file = file.replace("example.gitignore", ".gitignore");
161
+ if (!options.useSrcDir || !isNext) {
162
+ return file;
163
+ }
164
+ if (path.basename(file) === "mdx-components.tsx" || isRelative("app", file) || isRelative("lib", file)) {
165
+ return path.join(dest, "src", path.relative(dest, file));
166
+ }
167
+ return file;
168
+ }
169
+ if (isNext) {
170
+ await copy(path.join(sourceDir, `template/+next`), dest, defaultRename);
171
+ await copy(
172
+ path.join(sourceDir, `template/${options.template}`),
173
+ dest,
174
+ defaultRename
175
+ );
176
+ if (options.tailwindcss) {
177
+ await copy(
178
+ path.join(sourceDir, `template/+next+tailwindcss`),
179
+ dest,
180
+ defaultRename
181
+ );
182
+ log("Configured Tailwind CSS");
183
+ }
184
+ if (options.eslint) {
185
+ await copy(
186
+ path.join(sourceDir, `template/+next+eslint`),
187
+ dest,
188
+ defaultRename
189
+ );
190
+ log("Configured ESLint");
191
+ }
192
+ if (options.useSrcDir) {
193
+ const tsconfigPath = path.join(dest, "tsconfig.json");
194
+ const content = (await fs2.readFile(tsconfigPath)).toString();
195
+ const config = JSON.parse(content);
196
+ if (config.compilerOptions?.paths) {
197
+ Object.assign(config.compilerOptions.paths, {
198
+ "@/*": ["./src/*"]
199
+ });
200
+ }
201
+ await fs2.writeFile(tsconfigPath, JSON.stringify(config, null, 2));
202
+ }
203
+ } else {
204
+ await copy(
205
+ path.join(sourceDir, `template/${options.template}`),
206
+ dest,
207
+ defaultRename
208
+ );
209
+ }
210
+ const packageJson = await createPackageJson(projectName, dest, options);
211
+ await fs2.writeFile(
212
+ path.join(dest, "package.json"),
213
+ JSON.stringify(packageJson, null, 2)
214
+ );
215
+ const readMe = await getReadme(dest, projectName);
216
+ await fs2.writeFile(path.join(dest, "README.md"), readMe);
217
+ if (installDeps) {
218
+ try {
219
+ await autoInstall(options.packageManager, dest);
220
+ log("Installed dependencies");
221
+ } catch (err) {
222
+ log(`Failed to install dependencies: ${err}`);
223
+ }
224
+ }
225
+ if (initializeGit && await tryGitInit(dest)) {
226
+ log("Initialized Git repository");
227
+ }
228
+ }
229
+ async function getReadme(dest, projectName) {
230
+ const template = await fs2.readFile(path.join(dest, "README.md")).then((res) => res.toString());
231
+ return `# ${projectName}
232
+
233
+ ${template}`;
234
+ }
235
+ async function copy(from, to, rename = (s) => s) {
236
+ const stats = await fs2.stat(from);
237
+ if (stats.isDirectory()) {
238
+ const files = await fs2.readdir(from);
239
+ await Promise.all(
240
+ files.map(
241
+ (file) => copy(path.join(from, file), rename(path.join(to, file)))
242
+ )
243
+ );
244
+ } else {
245
+ await fs2.mkdir(path.dirname(to), { recursive: true });
246
+ await fs2.copyFile(from, to);
247
+ }
248
+ }
249
+ async function createPackageJson(projectName, dir, options) {
250
+ function replaceWorkspaceDeps(deps) {
251
+ for (const k in deps) {
252
+ if (deps[k].startsWith("workspace:") && k in versions) {
253
+ deps[k] = versions[k];
254
+ }
255
+ }
256
+ return deps;
257
+ }
258
+ if (options.template === "tanstack-start" || options.template === "react-router") {
259
+ const packageJson = JSON.parse(
260
+ await fs2.readFile(path.join(dir, "package.json")).then((res) => res.toString())
261
+ );
262
+ return {
263
+ name: projectName,
264
+ ...packageJson,
265
+ dependencies: replaceWorkspaceDeps(packageJson.dependencies),
266
+ devDependencies: replaceWorkspaceDeps(packageJson.devDependencies)
267
+ };
268
+ }
269
+ return {
270
+ name: projectName,
271
+ version: "0.0.0",
272
+ private: true,
273
+ scripts: {
274
+ build: "next build",
275
+ dev: "next dev --turbo",
276
+ start: "next start",
277
+ ...options.template === "+next+fuma-docs-mdx" ? {
278
+ postinstall: "fumadocs-mdx"
279
+ } : null
280
+ },
281
+ dependencies: {
282
+ ...pick(package_default.dependencies, ["next", "react", "react-dom"]),
283
+ ...pick(versions, ["fumadocs-ui", "fumadocs-core"]),
284
+ ...options.template === "+next+content-collections" ? {
285
+ ...pick(package_default.dependencies, [
286
+ "@content-collections/mdx",
287
+ "@content-collections/core",
288
+ "@content-collections/next"
289
+ ]),
290
+ ...pick(versions, ["@fumadocs/content-collections"])
291
+ } : null,
292
+ ...options.template === "+next+fuma-docs-mdx" ? pick(versions, ["fumadocs-mdx"]) : null
293
+ },
294
+ devDependencies: {
295
+ ...pick(package_default.dependencies, [
296
+ "@types/node",
297
+ "@types/react",
298
+ "@types/react-dom",
299
+ "typescript",
300
+ "@types/mdx"
301
+ ]),
302
+ ...options.tailwindcss ? pick(package_default.dependencies, [
303
+ "@tailwindcss/postcss",
304
+ "tailwindcss",
305
+ "postcss"
306
+ ]) : null,
307
+ ...options.eslint ? {
308
+ eslint: "^8",
309
+ "eslint-config-next": package_default.dependencies.next
310
+ } : null
311
+ }
312
+ };
313
+ }
314
+ function pick(obj, keys) {
315
+ const result = {};
316
+ for (const key of keys) {
317
+ if (key in obj) {
318
+ result[key] = obj[key];
319
+ }
320
+ }
321
+ return result;
322
+ }
323
+
324
+ export {
325
+ managers,
326
+ getPackageManager,
327
+ cwd,
328
+ templates,
329
+ create
330
+ };
@@ -1,6 +1,8 @@
1
- type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
1
+ type PackageManager = (typeof managers)[number];
2
+ declare const managers: readonly ["npm", "yarn", "bun", "pnpm"];
2
3
 
3
- type Template = '+next+content-collections' | '+next+fuma-docs-mdx' | 'react-router' | 'tanstack-start';
4
+ declare const templates: readonly ["+next+content-collections", "+next+fuma-docs-mdx", "react-router", "tanstack-start"];
5
+ type Template = (typeof templates)[number];
4
6
  interface Options {
5
7
  outputDir: string;
6
8
  template: Template;
@@ -32,4 +34,4 @@ interface Options {
32
34
  }
33
35
  declare function create(options: Options): Promise<void>;
34
36
 
35
- export { type Options, type Template, create };
37
+ export { type Options, type Template, create, templates };
@@ -1,6 +1,8 @@
1
1
  import {
2
- create
3
- } from "./chunk-FAFA6275.js";
2
+ create,
3
+ templates
4
+ } from "./chunk-J4NXLHNR.js";
4
5
  export {
5
- create
6
+ create,
7
+ templates
6
8
  };
package/dist/index.js CHANGED
@@ -2,8 +2,10 @@
2
2
  import {
3
3
  create,
4
4
  cwd,
5
- getPackageManager
6
- } from "./chunk-FAFA6275.js";
5
+ getPackageManager,
6
+ managers,
7
+ templates
8
+ } from "./chunk-J4NXLHNR.js";
7
9
 
8
10
  // src/index.ts
9
11
  import fs from "fs/promises";
@@ -20,42 +22,77 @@ import {
20
22
  text
21
23
  } from "@clack/prompts";
22
24
  import pc from "picocolors";
23
- var manager = getPackageManager();
24
- async function main() {
25
+ import { program } from "commander";
26
+ program.argument("[name]", "the project name");
27
+ program.option("--src", "(Next.js only) enable `src/` directory");
28
+ program.option("--no-src", "(Next.js only) disable `src/` directory");
29
+ program.option("--eslint", "(Next.js only) enable ESLint configuration");
30
+ program.option("--no-eslint", "(Next.js only) disable ESLint configuration");
31
+ program.option("--install", "Enable installing packages automatically");
32
+ program.option("--no-install", "Disable installing packages automatically");
33
+ program.option(
34
+ "--template <name>",
35
+ `template to choose: ${templates.join(", ")}`,
36
+ (value) => {
37
+ if (!templates.includes(value)) {
38
+ throw new Error(`Invalid template: ${value}.`);
39
+ }
40
+ return value;
41
+ }
42
+ );
43
+ program.option(
44
+ "--pm <name>",
45
+ `package manager to choose: ${managers.join(", ")}`,
46
+ (value) => {
47
+ if (!managers.includes(value)) {
48
+ throw new Error(`Invalid package manager: ${value}.`);
49
+ }
50
+ return value;
51
+ }
52
+ );
53
+ async function main(config) {
25
54
  intro(pc.bgCyan(pc.bold("Create Fumadocs App")));
55
+ const manager = config.pm ?? getPackageManager();
26
56
  const options = await group(
27
57
  {
28
- name: () => text({
29
- message: "Project name",
30
- placeholder: "my-app",
31
- defaultValue: "my-app"
32
- }),
33
- template: () => select({
34
- message: "Choose a template",
35
- initialValue: "+next+fuma-docs-mdx",
36
- options: [
37
- {
38
- value: "+next+fuma-docs-mdx",
39
- label: "Next.js: Fumadocs MDX",
40
- hint: "recommended"
41
- },
42
- {
43
- value: "+next+content-collections",
44
- label: "Next.js: Content Collections"
45
- },
46
- {
47
- value: "react-router",
48
- label: "React Router: MDX Remote"
49
- },
50
- {
51
- value: "tanstack-start",
52
- label: "Tanstack Start: MDX Remote",
53
- hint: "Experimental"
54
- }
55
- ]
56
- }),
58
+ name: () => {
59
+ if (config.name) return Promise.resolve(config.name);
60
+ return text({
61
+ message: "Project name",
62
+ placeholder: "my-app",
63
+ defaultValue: "my-app"
64
+ });
65
+ },
66
+ template: () => {
67
+ if (config.template) return Promise.resolve(config.template);
68
+ return select({
69
+ message: "Choose a template",
70
+ initialValue: "+next+fuma-docs-mdx",
71
+ options: [
72
+ {
73
+ value: "+next+fuma-docs-mdx",
74
+ label: "Next.js: Fumadocs MDX",
75
+ hint: "recommended"
76
+ },
77
+ {
78
+ value: "+next+content-collections",
79
+ label: "Next.js: Content Collections"
80
+ },
81
+ {
82
+ value: "react-router",
83
+ label: "React Router: MDX Remote"
84
+ },
85
+ {
86
+ value: "tanstack-start",
87
+ label: "Tanstack Start: MDX Remote",
88
+ hint: "Experimental"
89
+ }
90
+ ]
91
+ });
92
+ },
57
93
  src: (v) => {
58
94
  if (!v.results.template?.startsWith("+next")) return;
95
+ if (config.src !== void 0) return Promise.resolve(config.src);
59
96
  return confirm({
60
97
  message: "Use `/src` directory?",
61
98
  initialValue: false
@@ -63,14 +100,19 @@ async function main() {
63
100
  },
64
101
  eslint: (v) => {
65
102
  if (!v.results.template?.startsWith("+next")) return;
103
+ if (config.eslint !== void 0) return Promise.resolve(config.eslint);
66
104
  return confirm({
67
105
  message: "Add default ESLint configuration?",
68
106
  initialValue: false
69
107
  });
70
108
  },
71
- installDeps: () => confirm({
72
- message: `Do you want to install packages automatically? (detected as ${manager})`
73
- })
109
+ installDeps: () => {
110
+ if (config.install !== void 0)
111
+ return Promise.resolve(config.install);
112
+ return confirm({
113
+ message: `Do you want to install packages automatically? (detected as ${manager})`
114
+ });
115
+ }
74
116
  },
75
117
  {
76
118
  onCancel: () => {
@@ -129,7 +171,11 @@ async function main() {
129
171
  );
130
172
  process.exit(0);
131
173
  }
132
- main().catch((e) => {
174
+ program.parse();
175
+ main({
176
+ name: program.args[0],
177
+ ...program.opts()
178
+ }).catch((e) => {
133
179
  console.error(e);
134
- throw e;
180
+ process.exit(1);
135
181
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fumadocs-app",
3
- "version": "15.6.3",
3
+ "version": "15.6.5",
4
4
  "description": "Create a new documentation site with Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -22,12 +22,13 @@
22
22
  ],
23
23
  "dependencies": {
24
24
  "@clack/prompts": "^0.11.0",
25
- "cross-spawn": "^7.0.6",
26
- "picocolors": "^1.1.1"
25
+ "commander": "^14.0.0",
26
+ "picocolors": "^1.1.1",
27
+ "tinyexec": "^1.0.1"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@types/cross-spawn": "^6.0.6",
30
- "@types/node": "24.0.7",
31
+ "@types/node": "24.0.15",
31
32
  "tinyglobby": "^0.2.14",
32
33
  "eslint-config-custom": "0.0.0",
33
34
  "tsconfig": "0.0.0"
@@ -13,12 +13,6 @@ import type { PageTree } from 'fumadocs-core/server';
13
13
  import { createCompiler } from '@fumadocs/mdx-remote';
14
14
  import * as path from 'node:path';
15
15
 
16
- export function meta({}: Route.MetaArgs) {
17
- return [
18
- { title: 'New React Router App' },
19
- { name: 'description', content: 'Welcome to React Router!' },
20
- ];
21
- }
22
16
  const compiler = createCompiler({
23
17
  development: false,
24
18
  });
@@ -26,10 +20,10 @@ const compiler = createCompiler({
26
20
  export async function loader({ params }: Route.LoaderArgs) {
27
21
  const slugs = params['*'].split('/').filter((v) => v.length > 0);
28
22
  const page = source.getPage(slugs);
29
- if (!page) throw new Error('Not found');
23
+ if (!page) throw new Response('Not found', { status: 404 });
30
24
 
31
25
  const compiled = await compiler.compileFile({
32
- path: path.resolve('content/docs', page.file.path),
26
+ path: path.resolve('content/docs', page.path),
33
27
  value: page.data.content,
34
28
  });
35
29
 
@@ -51,6 +45,8 @@ export default function Page(props: Route.ComponentProps) {
51
45
  }}
52
46
  tree={tree as PageTree.Root}
53
47
  >
48
+ <title>{page.data.title}</title>
49
+ <meta name="description" content={page.data.description} />
54
50
  <DocsPage toc={toc}>
55
51
  <DocsTitle>{page.data.title}</DocsTitle>
56
52
  <DocsDescription>{page.data.description}</DocsDescription>
@@ -12,14 +12,13 @@ export function meta({}: Route.MetaArgs) {
12
12
  export default function Home() {
13
13
  return (
14
14
  <HomeLayout
15
- className="text-center"
16
15
  nav={{
17
16
  title: 'React Router',
18
17
  }}
19
18
  >
20
- <div className="py-12">
19
+ <div className="p-4 flex flex-col items-center justify-center text-center flex-1">
21
20
  <h1 className="text-xl font-bold mb-2">Fumadocs on React Router.</h1>
22
- <p className="text-fd-muted-foreground mb-8">
21
+ <p className="text-fd-muted-foreground mb-4">
23
22
  The truly flexible docs framework on React.js.
24
23
  </p>
25
24
  <Link
@@ -1,8 +1,24 @@
1
1
  ---
2
- title: Fumadocs
3
- description: You can just be minimal.
2
+ title: Test
3
+ description: A document to test Fumadocs
4
4
  ---
5
5
 
6
- ## Overview
6
+ Hey there!
7
7
 
8
- Fumadocs is a docs framework.
8
+ ## Cards
9
+
10
+ <Cards>
11
+ <Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
12
+ <Card title="Learn more about Fumadocs" href="https://fumadocs.vercel.app" />
13
+ </Cards>
14
+
15
+ ### CodeBlock
16
+
17
+ ```js
18
+ console.log('Hello World');
19
+ ```
20
+
21
+ #### List
22
+
23
+ - Hello
24
+ - World
@@ -0,0 +1,35 @@
1
+ {
2
+ "private": true,
3
+ "type": "module",
4
+ "scripts": {
5
+ "build": "react-router build",
6
+ "dev": "react-router dev",
7
+ "start": "react-router-serve ./build/server/index.js",
8
+ "typecheck": "react-router typegen && tsc"
9
+ },
10
+ "dependencies": {
11
+ "@fumadocs/mdx-remote": "workspace:*",
12
+ "@react-router/node": "^7.6.3",
13
+ "@react-router/serve": "^7.6.3",
14
+ "fumadocs-core": "workspace:*",
15
+ "fumadocs-ui": "workspace:*",
16
+ "gray-matter": "^4.0.3",
17
+ "isbot": "^5.1.28",
18
+ "react": "^19.1.0",
19
+ "react-dom": "^19.1.0",
20
+ "react-router": "^7.6.3",
21
+ "shiki": "^3.8.0"
22
+ },
23
+ "devDependencies": {
24
+ "@react-router/dev": "^7.6.3",
25
+ "@tailwindcss/vite": "^4.1.11",
26
+ "@types/node": "^24.0.13",
27
+ "@types/react": "^19.1.8",
28
+ "@types/react-dom": "^19.1.6",
29
+ "react-router-devtools": "^5.0.6",
30
+ "tailwindcss": "^4.1.11",
31
+ "typescript": "^5.8.3",
32
+ "vite": "^7.0.4",
33
+ "vite-tsconfig-paths": "^5.1.4"
34
+ }
35
+ }
@@ -1,8 +1,7 @@
1
1
  ---
2
2
  title: Hello World
3
- description: |
4
- Your first `document`
5
- You'll love it!
3
+ description: Your favourite docs framework.
4
+ icon: Rocket
6
5
  ---
7
6
 
8
7
  Hey there! Fumadocs is a docs framework built for Next.js, but do you know it also works on Tanstack Start?
@@ -0,0 +1,10 @@
1
+ ---
2
+ title: Test
3
+ description: This is another page
4
+ ---
5
+
6
+ Hello World again!
7
+
8
+ ```npm
9
+ npm i fumadocs-core fumadocs-ui
10
+ ```