@presencenet/create-pnet-stack 0.0.0-stage → 0.2.1

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 (54) hide show
  1. package/bin/create-pnet-stack.js +106 -0
  2. package/package.json +26 -4
  3. package/templates/electron/apps/app/electron.vite.config.ts +13 -0
  4. package/templates/electron/apps/app/package.json +27 -0
  5. package/templates/electron/apps/app/src/main/index.ts +22 -0
  6. package/templates/electron/apps/app/src/preload/index.ts +3 -0
  7. package/templates/electron/apps/app/src/renderer/index.html +2 -0
  8. package/templates/electron/apps/app/src/renderer/src/main.tsx +26 -0
  9. package/templates/electron/apps/app/src/renderer/src/style.css +8 -0
  10. package/templates/electron/biome.json +7 -0
  11. package/templates/electron/gitignore +5 -0
  12. package/templates/electron/package.json +18 -0
  13. package/templates/electron/turbo.json +8 -0
  14. package/templates/mobile/apps/app/app/_layout.tsx +17 -0
  15. package/templates/mobile/apps/app/app/index.tsx +17 -0
  16. package/templates/mobile/apps/app/app.json +11 -0
  17. package/templates/mobile/apps/app/babel.config.js +9 -0
  18. package/templates/mobile/apps/app/global.css +3 -0
  19. package/templates/mobile/apps/app/metro.config.js +6 -0
  20. package/templates/mobile/apps/app/nativewind-env.d.ts +1 -0
  21. package/templates/mobile/apps/app/package.json +33 -0
  22. package/templates/mobile/apps/app/tailwind.config.js +7 -0
  23. package/templates/mobile/apps/app/tsconfig.json +11 -0
  24. package/templates/mobile/biome.json +18 -0
  25. package/templates/mobile/gitignore +6 -0
  26. package/templates/mobile/package.json +18 -0
  27. package/templates/mobile/turbo.json +8 -0
  28. package/templates/tauri/apps/app/index.html +2 -0
  29. package/templates/tauri/apps/app/package.json +28 -0
  30. package/templates/tauri/apps/app/src/main.tsx +26 -0
  31. package/templates/tauri/apps/app/src/style.css +8 -0
  32. package/templates/tauri/apps/app/src-tauri/Cargo.toml +20 -0
  33. package/templates/tauri/apps/app/src-tauri/build.rs +3 -0
  34. package/templates/tauri/apps/app/src-tauri/src/lib.rs +6 -0
  35. package/templates/tauri/apps/app/src-tauri/src/main.rs +5 -0
  36. package/templates/tauri/apps/app/src-tauri/tauri.conf.json +17 -0
  37. package/templates/tauri/apps/app/tsconfig.json +12 -0
  38. package/templates/tauri/apps/app/vite.config.ts +18 -0
  39. package/templates/tauri/biome.json +7 -0
  40. package/templates/tauri/gitignore +6 -0
  41. package/templates/tauri/package.json +18 -0
  42. package/templates/tauri/turbo.json +8 -0
  43. package/templates/web/apps/app/package.json +26 -0
  44. package/templates/web/apps/app/src/router.tsx +6 -0
  45. package/templates/web/apps/app/src/routes/__root.tsx +29 -0
  46. package/templates/web/apps/app/src/routes/index.tsx +19 -0
  47. package/templates/web/apps/app/src/styles.css +1 -0
  48. package/templates/web/apps/app/tsconfig.json +13 -0
  49. package/templates/web/apps/app/vite.config.ts +8 -0
  50. package/templates/web/biome.json +7 -0
  51. package/templates/web/gitignore +7 -0
  52. package/templates/web/package.json +18 -0
  53. package/templates/web/turbo.json +11 -0
  54. package/README.md +0 -3
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from "node:child_process";
3
+ import {
4
+ cp,
5
+ mkdir,
6
+ readdir,
7
+ readFile,
8
+ rename,
9
+ writeFile,
10
+ } from "node:fs/promises";
11
+ import { dirname, join, resolve } from "node:path";
12
+ import { stdin, stdout } from "node:process";
13
+ import { createInterface } from "node:readline/promises";
14
+ import { fileURLToPath } from "node:url";
15
+
16
+ const templates = ["web", "mobile", "electron", "tauri"];
17
+ const templateNames = {
18
+ web: "TanStack Start",
19
+ mobile: "React Native (Expo)",
20
+ electron: "Electron",
21
+ tauri: "Tauri",
22
+ };
23
+ const cliDir = dirname(dirname(fileURLToPath(import.meta.url)));
24
+
25
+ async function main() {
26
+ const args = process.argv.slice(2);
27
+ if (args.includes("--help") || args.includes("-h")) {
28
+ stdout.write(
29
+ "Usage: npx @presencenet/create-pnet-stack [project-name] [--template web|mobile|electron|tauri]\n",
30
+ );
31
+ return;
32
+ }
33
+ let projectName = args.find((arg) => !arg.startsWith("--"));
34
+ let template = args
35
+ .find((arg) => arg.startsWith("--template="))
36
+ ?.split("=")[1];
37
+ if (!template && args.includes("--template"))
38
+ template = args[args.indexOf("--template") + 1];
39
+
40
+ const rl = createInterface({ input: stdin, output: stdout });
41
+ if (!projectName) projectName = (await rl.question("Project name: ")).trim();
42
+ while (!templates.includes(template)) {
43
+ stdout.write(
44
+ `\nChoose a starter: ${templates.map((item, i) => `${i + 1}) ${templateNames[item]}`).join(" ")}\n`,
45
+ );
46
+ const answer = (await rl.question("Starter [1]: ")).trim() || "1";
47
+ template = templates[Number(answer) - 1] ?? answer;
48
+ if (!templates.includes(template))
49
+ stdout.write("Choose web, mobile, electron, or tauri.\n");
50
+ }
51
+ rl.close();
52
+
53
+ if (!projectName || !/^[a-z0-9][a-z0-9-]*$/.test(projectName))
54
+ throw new Error(
55
+ "Use a lowercase project name containing letters, numbers, or hyphens.",
56
+ );
57
+ const target = resolve(process.cwd(), projectName);
58
+ if (target === process.cwd())
59
+ throw new Error("Choose a project directory name.");
60
+ try {
61
+ if ((await readdir(target)).length)
62
+ throw new Error(`Target directory is not empty: ${target}`);
63
+ } catch (error) {
64
+ if (error.code !== "ENOENT") throw error;
65
+ }
66
+
67
+ const source = join(cliDir, "templates", template);
68
+ await mkdir(target, { recursive: true });
69
+ await cp(source, target, { recursive: true });
70
+ // npm strips .gitignore from published packages, so templates ship it as gitignore.
71
+ await rename(join(target, "gitignore"), join(target, ".gitignore"));
72
+ const rustName = projectName.replaceAll("-", "_");
73
+ await replaceTokens(target, {
74
+ "{{projectName}}": projectName,
75
+ "{{projectNameRust}}": rustName,
76
+ '"root": false': '"root": true',
77
+ });
78
+ execFileSync("git", ["init"], { cwd: target, stdio: "ignore" });
79
+ stdout.write(`\nCreated ${projectName} (${templateNames[template]}).\n`);
80
+ stdout.write("Initialized Git repository.\n");
81
+ stdout.write(`\n cd ${projectName}\n bun install\n bun run dev\n`);
82
+ if (template === "tauri")
83
+ stdout.write(
84
+ "\nTauri also requires the platform prerequisites: https://tauri.app/start/prerequisites/\n",
85
+ );
86
+ }
87
+
88
+ async function replaceTokens(directory, replacements) {
89
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
90
+ const path = join(directory, entry.name);
91
+ if (entry.isDirectory()) await replaceTokens(path, replacements);
92
+ else {
93
+ const contents = await readFile(path, "utf8");
94
+ const updated = Object.entries(replacements).reduce(
95
+ (text, [token, value]) => text.replaceAll(token, value),
96
+ contents,
97
+ );
98
+ if (updated !== contents) await writeFile(path, updated);
99
+ }
100
+ }
101
+ }
102
+
103
+ main().catch((error) => {
104
+ process.stderr.write(`\ncreate-pnet-stack: ${error.message}\n`);
105
+ process.exitCode = 1;
106
+ });
package/package.json CHANGED
@@ -1,6 +1,28 @@
1
1
  {
2
2
  "name": "@presencenet/create-pnet-stack",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.1",
4
+ "description": "Create a Bun and Turborepo app with pnet-stack",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-pnet-stack": "./bin/create-pnet-stack.js"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/Presence-Net/pnet-stack.git",
12
+ "directory": "packages/create-pnet-stack"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "files": [
18
+ "bin",
19
+ "templates"
20
+ ],
21
+ "engines": {
22
+ "node": ">=18"
23
+ },
24
+ "scripts": {
25
+ "build": "node --check bin/create-pnet-stack.js",
26
+ "check": "biome check bin"
27
+ }
28
+ }
@@ -0,0 +1,13 @@
1
+ import { resolve } from "node:path";
2
+ import tailwindcss from "@tailwindcss/vite";
3
+ import react from "@vitejs/plugin-react";
4
+ import { defineConfig, externalizeDepsPlugin } from "electron-vite";
5
+
6
+ export default defineConfig({
7
+ main: { plugins: [externalizeDepsPlugin()] },
8
+ preload: { plugins: [externalizeDepsPlugin()] },
9
+ renderer: {
10
+ resolve: { alias: { "@": resolve("src/renderer/src") } },
11
+ plugins: [react(), tailwindcss()],
12
+ },
13
+ });
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@{{projectName}}/app",
3
+ "private": true,
4
+ "type": "module",
5
+ "main": "out/main/index.js",
6
+ "scripts": {
7
+ "dev": "electron-vite dev",
8
+ "build": "electron-vite build",
9
+ "check": "biome check ."
10
+ },
11
+ "dependencies": {
12
+ "@tailwindcss/vite": "^4.3.4",
13
+ "react": "^19.3.0",
14
+ "react-dom": "^19.3.0",
15
+ "tailwindcss": "^4.3.4"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^26.6.6",
19
+ "@types/react": "^19.3.0",
20
+ "@types/react-dom": "^19.3.0",
21
+ "@vitejs/plugin-react": "^6.2.1",
22
+ "electron": "^45.2.2",
23
+ "electron-vite": "^6.0.0",
24
+ "typescript": "^6.0.3",
25
+ "vite": "^8.3.5"
26
+ }
27
+ }
@@ -0,0 +1,22 @@
1
+ import { join } from "node:path";
2
+ import { app, BrowserWindow } from "electron";
3
+
4
+ function createWindow() {
5
+ const window = new BrowserWindow({
6
+ width: 1100,
7
+ height: 760,
8
+ webPreferences: {
9
+ preload: join(__dirname, "../preload/index.js"),
10
+ contextIsolation: true,
11
+ nodeIntegration: false,
12
+ },
13
+ });
14
+ if (process.env.ELECTRON_RENDERER_URL)
15
+ window.loadURL(process.env.ELECTRON_RENDERER_URL);
16
+ else window.loadFile(join(__dirname, "../renderer/index.html"));
17
+ }
18
+
19
+ app.whenReady().then(createWindow);
20
+ app.on("window-all-closed", () => {
21
+ if (process.platform !== "darwin") app.quit();
22
+ });
@@ -0,0 +1,3 @@
1
+ import { contextBridge } from "electron";
2
+
3
+ contextBridge.exposeInMainWorld("appInfo", { name: "{{projectName}}" });
@@ -0,0 +1,2 @@
1
+ <!doctype html>
2
+ <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>{{projectName}}</title></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body></html>
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import "./style.css";
4
+
5
+ function App() {
6
+ return (
7
+ <main className="flex min-h-screen flex-col justify-center px-12">
8
+ <p className="text-sm font-bold uppercase tracking-widest text-cyan-300">
9
+ Presence-Net starter
10
+ </p>
11
+ <h1 className="mt-3 text-5xl font-bold">{"{{projectName}}"}</h1>
12
+ <p className="mt-5 text-lg text-slate-300">
13
+ Electron, React, Tailwind, and a Bun-powered Turborepo workspace.
14
+ </p>
15
+ </main>
16
+ );
17
+ }
18
+
19
+ const root = document.getElementById("root");
20
+ if (!root) throw new Error("Root element not found");
21
+
22
+ createRoot(root).render(
23
+ <React.StrictMode>
24
+ <App />
25
+ </React.StrictMode>,
26
+ );
@@ -0,0 +1,8 @@
1
+ @import "tailwindcss";
2
+
3
+ :root {
4
+ color-scheme: dark;
5
+ font-family: system-ui, sans-serif;
6
+ background: #020617;
7
+ color: white;
8
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "root": false,
3
+ "$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
4
+ "formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
5
+ "linter": { "enabled": true, "rules": { "preset": "recommended" } },
6
+ "javascript": { "formatter": { "quoteStyle": "double" } }
7
+ }
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ dist
3
+ .turbo
4
+ .env*
5
+ !.env.example
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "packageManager": "bun@1.3.14",
5
+ "workspaces": [
6
+ "apps/*",
7
+ "packages/*"
8
+ ],
9
+ "scripts": {
10
+ "dev": "turbo run dev",
11
+ "build": "turbo run build",
12
+ "check": "turbo run check"
13
+ },
14
+ "devDependencies": {
15
+ "@biomejs/biome": "2.6.5",
16
+ "turbo": "^2.5.0"
17
+ }
18
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "tasks": {
4
+ "build": { "dependsOn": ["^build"], "outputs": ["out/**"] },
5
+ "dev": { "cache": false, "persistent": true },
6
+ "check": { "dependsOn": ["^check"] }
7
+ }
8
+ }
@@ -0,0 +1,17 @@
1
+ import "../global.css";
2
+ import { Stack } from "expo-router";
3
+ import { StatusBar } from "expo-status-bar";
4
+
5
+ export default function Layout() {
6
+ return (
7
+ <>
8
+ <StatusBar style="light" />
9
+ <Stack
10
+ screenOptions={{
11
+ contentStyle: { backgroundColor: "#020617" },
12
+ headerShown: false,
13
+ }}
14
+ />
15
+ </>
16
+ );
17
+ }
@@ -0,0 +1,17 @@
1
+ import { Text, View } from "react-native";
2
+
3
+ export default function Home() {
4
+ return (
5
+ <View className="flex-1 items-center justify-center bg-slate-950 px-8">
6
+ <Text className="text-sm font-bold uppercase tracking-widest text-cyan-300">
7
+ Presence-Net starter
8
+ </Text>
9
+ <Text className="mt-3 text-4xl font-bold text-white">
10
+ {"{{projectName}}"}
11
+ </Text>
12
+ <Text className="mt-4 text-center text-lg text-slate-300">
13
+ React Native, NativeWind, and a Bun-powered Turborepo workspace.
14
+ </Text>
15
+ </View>
16
+ );
17
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "expo": {
3
+ "name": "{{projectName}}",
4
+ "slug": "{{projectName}}",
5
+ "scheme": "{{projectName}}",
6
+ "plugins": ["expo-router"],
7
+ "experiments": { "typedRoutes": true },
8
+ "ios": { "supportsTablet": true },
9
+ "android": { "package": "net.presence.{{projectNameRust}}" }
10
+ }
11
+ }
@@ -0,0 +1,9 @@
1
+ module.exports = (api) => {
2
+ api.cache(true);
3
+ return {
4
+ presets: [
5
+ ["babel-preset-expo", { jsxImportSource: "nativewind" }],
6
+ "nativewind/babel",
7
+ ],
8
+ };
9
+ };
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -0,0 +1,6 @@
1
+ const { getDefaultConfig } = require("expo/metro-config");
2
+ const { withNativeWind } = require("nativewind/metro");
3
+
4
+ module.exports = withNativeWind(getDefaultConfig(__dirname), {
5
+ input: "./global.css",
6
+ });
@@ -0,0 +1 @@
1
+ /// <reference types="nativewind/types" />
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@{{projectName}}/app",
3
+ "private": true,
4
+ "main": "expo-router/entry",
5
+ "scripts": {
6
+ "dev": "expo start",
7
+ "build": "expo export",
8
+ "check": "biome check ."
9
+ },
10
+ "dependencies": {
11
+ "expo": "~58.0.23",
12
+ "expo-constants": "~58.0.15",
13
+ "expo-linking": "~58.0.16",
14
+ "expo-router": "~58.0.30",
15
+ "expo-splash-screen": "~58.0.13",
16
+ "expo-status-bar": "~58.0.4",
17
+ "nativewind": "^4.2.7",
18
+ "react": "19.3.0",
19
+ "react-native": "0.88.1",
20
+ "react-native-reanimated": "4.7.1",
21
+ "react-native-gesture-handler": "~3.3.0",
22
+ "react-native-safe-area-context": "~5.11.1",
23
+ "react-native-screens": "~4.30.1",
24
+ "react-native-worklets": "0.13.0"
25
+ },
26
+ "devDependencies": {
27
+ "@babel/core": "^7.29.7",
28
+ "@types/react": "~19.3.0",
29
+ "babel-preset-expo": "~58.0.0",
30
+ "tailwindcss": "^3.4.17",
31
+ "typescript": "~6.0.3"
32
+ }
33
+ }
@@ -0,0 +1,7 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ content: ["./app/**/*.{js,jsx,ts,tsx}"],
4
+ presets: [require("nativewind/preset")],
5
+ theme: { extend: {} },
6
+ plugins: [],
7
+ };
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "expo/tsconfig.base",
3
+ "compilerOptions": { "strict": true, "paths": { "@/*": ["./*"] } },
4
+ "include": [
5
+ "**/*.ts",
6
+ "**/*.tsx",
7
+ ".expo/types/**/*.ts",
8
+ "expo-env.d.ts",
9
+ "nativewind-env.d.ts"
10
+ ]
11
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "root": false,
3
+ "$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
4
+ "formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
5
+ "linter": {
6
+ "enabled": true,
7
+ "rules": {
8
+ "preset": "recommended",
9
+ "suspicious": {
10
+ "noUnknownAtRules": {
11
+ "level": "on",
12
+ "options": { "ignore": ["tailwind"] }
13
+ }
14
+ }
15
+ }
16
+ },
17
+ "javascript": { "formatter": { "quoteStyle": "double" } }
18
+ }
@@ -0,0 +1,6 @@
1
+ node_modules
2
+ .expo
3
+ dist
4
+ .turbo
5
+ .env*
6
+ !.env.example
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "packageManager": "bun@1.3.14",
5
+ "workspaces": [
6
+ "apps/*",
7
+ "packages/*"
8
+ ],
9
+ "scripts": {
10
+ "dev": "turbo run dev",
11
+ "build": "turbo run build",
12
+ "check": "turbo run check"
13
+ },
14
+ "devDependencies": {
15
+ "@biomejs/biome": "2.6.5",
16
+ "turbo": "^2.5.0"
17
+ }
18
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "tasks": {
4
+ "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
5
+ "dev": { "cache": false, "persistent": true },
6
+ "check": { "dependsOn": ["^check"] }
7
+ }
8
+ }
@@ -0,0 +1,2 @@
1
+ <!doctype html>
2
+ <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>{{projectName}}</title></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body></html>
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@{{projectName}}/app",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "tauri dev",
7
+ "build": "tauri build",
8
+ "web:dev": "vite --host 0.0.0.0",
9
+ "web:build": "vite build",
10
+ "check": "biome check ."
11
+ },
12
+ "dependencies": {
13
+ "@tailwindcss/vite": "^4.3.4",
14
+ "@tauri-apps/api": "^2.12.4",
15
+ "react": "^19.3.0",
16
+ "react-dom": "^19.3.0",
17
+ "tailwindcss": "^4.3.4"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^26.6.6",
21
+ "@types/react": "^19.3.0",
22
+ "@types/react-dom": "^19.3.0",
23
+ "@tauri-apps/cli": "^2.12.4",
24
+ "@vitejs/plugin-react": "^6.2.1",
25
+ "typescript": "^6.0.3",
26
+ "vite": "^8.3.5"
27
+ }
28
+ }
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import "./style.css";
4
+
5
+ function App() {
6
+ return (
7
+ <main className="flex min-h-screen flex-col justify-center px-12">
8
+ <p className="text-sm font-bold uppercase tracking-widest text-cyan-300">
9
+ Presence-Net starter
10
+ </p>
11
+ <h1 className="mt-3 text-5xl font-bold">{"{{projectName}}"}</h1>
12
+ <p className="mt-5 text-lg text-slate-300">
13
+ Tauri, React, Tailwind, and a Bun-powered Turborepo workspace.
14
+ </p>
15
+ </main>
16
+ );
17
+ }
18
+
19
+ const root = document.getElementById("root");
20
+ if (!root) throw new Error("Root element not found");
21
+
22
+ createRoot(root).render(
23
+ <React.StrictMode>
24
+ <App />
25
+ </React.StrictMode>,
26
+ );
@@ -0,0 +1,8 @@
1
+ @import "tailwindcss";
2
+
3
+ :root {
4
+ color-scheme: dark;
5
+ font-family: system-ui, sans-serif;
6
+ background: #020617;
7
+ color: white;
8
+ }
@@ -0,0 +1,20 @@
1
+ [package]
2
+ name = "{{projectName}}"
3
+ version = "0.1.0"
4
+ description = "A Presence-Net desktop app"
5
+ authors = ["Presence-Net"]
6
+ edition = "2021"
7
+
8
+ [lib]
9
+ name = "{{projectNameRust}}_lib"
10
+ crate-type = ["staticlib", "cdylib", "rlib"]
11
+
12
+ [build-dependencies]
13
+ tauri-build = { version = "2", features = [] }
14
+
15
+ [dependencies]
16
+ tauri = { version = "2", features = [] }
17
+
18
+ [features]
19
+ default = ["custom-protocol"]
20
+ custom-protocol = ["tauri/custom-protocol"]
@@ -0,0 +1,3 @@
1
+ fn main() {
2
+ tauri_build::build()
3
+ }
@@ -0,0 +1,6 @@
1
+ #[cfg_attr(mobile, tauri::mobile_entry_point)]
2
+ pub fn run() {
3
+ tauri::Builder::default()
4
+ .run(tauri::generate_context!())
5
+ .expect("error while running tauri application");
6
+ }
@@ -0,0 +1,5 @@
1
+ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
2
+
3
+ fn main() {
4
+ {{projectNameRust}}_lib::run()
5
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://schema.tauri.app/config/2",
3
+ "productName": "{{projectName}}",
4
+ "version": "0.1.0",
5
+ "identifier": "net.presence.{{projectName}}",
6
+ "build": {
7
+ "beforeDevCommand": "bun run web:dev",
8
+ "devUrl": "http://localhost:1420",
9
+ "beforeBuildCommand": "bun run web:build",
10
+ "frontendDist": "../dist"
11
+ },
12
+ "app": {
13
+ "windows": [{ "title": "{{projectName}}", "width": 1100, "height": 760 }],
14
+ "security": { "csp": null }
15
+ },
16
+ "bundle": { "active": true, "targets": "all" }
17
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "jsx": "react-jsx",
8
+ "strict": true,
9
+ "skipLibCheck": true
10
+ },
11
+ "include": ["src"]
12
+ }
@@ -0,0 +1,18 @@
1
+ import tailwindcss from "@tailwindcss/vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import { defineConfig } from "vite";
4
+
5
+ export default defineConfig({
6
+ clearScreen: false,
7
+ server: {
8
+ host: process.env.TAURI_DEV_HOST || "0.0.0.0",
9
+ port: 1420,
10
+ strictPort: true,
11
+ watch: { ignored: ["**/src-tauri/**"] },
12
+ },
13
+ plugins: [react(), tailwindcss()],
14
+ build: {
15
+ target:
16
+ process.env.TAURI_ENV_PLATFORM === "windows" ? "chrome105" : "safari13",
17
+ },
18
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "root": false,
3
+ "$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
4
+ "formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
5
+ "linter": { "enabled": true, "rules": { "preset": "recommended" } },
6
+ "javascript": { "formatter": { "quoteStyle": "double" } }
7
+ }
@@ -0,0 +1,6 @@
1
+ node_modules
2
+ dist
3
+ .turbo
4
+ src-tauri/target
5
+ .env*
6
+ !.env.example
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "packageManager": "bun@1.3.14",
5
+ "workspaces": [
6
+ "apps/*",
7
+ "packages/*"
8
+ ],
9
+ "scripts": {
10
+ "dev": "turbo run dev",
11
+ "build": "turbo run build",
12
+ "check": "turbo run check"
13
+ },
14
+ "devDependencies": {
15
+ "@biomejs/biome": "2.6.5",
16
+ "turbo": "^2.5.0"
17
+ }
18
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "tasks": {
4
+ "build": { "dependsOn": ["^build"], "cache": false },
5
+ "dev": { "cache": false, "persistent": true },
6
+ "check": { "dependsOn": ["^check"] }
7
+ }
8
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@{{projectName}}/app",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "vite dev",
7
+ "build": "vite build",
8
+ "check": "biome check ."
9
+ },
10
+ "dependencies": {
11
+ "@tanstack/react-router": "^1.170.46",
12
+ "@tanstack/react-start": "^1.169.4",
13
+ "react": "^19.3.0",
14
+ "react-dom": "^19.3.0"
15
+ },
16
+ "devDependencies": {
17
+ "@tailwindcss/vite": "^4.3.4",
18
+ "@types/node": "^26.6.6",
19
+ "@types/react": "^19.3.0",
20
+ "@types/react-dom": "^19.3.0",
21
+ "@vitejs/plugin-react": "^6.2.1",
22
+ "tailwindcss": "^4.3.4",
23
+ "typescript": "^6.0.3",
24
+ "vite": "^8.3.5"
25
+ }
26
+ }
@@ -0,0 +1,6 @@
1
+ import { createRouter } from "@tanstack/react-router";
2
+ import { routeTree } from "./routeTree.gen";
3
+
4
+ export function getRouter() {
5
+ return createRouter({ routeTree, scrollRestoration: true });
6
+ }
@@ -0,0 +1,29 @@
1
+ import {
2
+ createRootRoute,
3
+ HeadContent,
4
+ Outlet,
5
+ Scripts,
6
+ } from "@tanstack/react-router";
7
+ import "../styles.css";
8
+
9
+ export const Route = createRootRoute({
10
+ head: () => ({
11
+ meta: [
12
+ { charSet: "utf-8" },
13
+ { name: "viewport", content: "width=device-width, initial-scale=1" },
14
+ { title: "{{projectName}}" },
15
+ { name: "description", content: "A Presence-Net app" },
16
+ ],
17
+ }),
18
+ component: () => (
19
+ <html lang="en">
20
+ <head>
21
+ <HeadContent />
22
+ </head>
23
+ <body className="min-h-screen bg-slate-950 text-white antialiased">
24
+ <Outlet />
25
+ <Scripts />
26
+ </body>
27
+ </html>
28
+ ),
29
+ });
@@ -0,0 +1,19 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+
3
+ export const Route = createFileRoute("/")({
4
+ component: Home,
5
+ });
6
+
7
+ function Home() {
8
+ return (
9
+ <main className="mx-auto flex min-h-screen max-w-3xl flex-col justify-center px-8">
10
+ <p className="mb-3 text-sm font-semibold uppercase tracking-[0.2em] text-cyan-300">
11
+ Presence-Net starter
12
+ </p>
13
+ <h1 className="text-5xl font-bold tracking-tight">{"{{projectName}}"}</h1>
14
+ <p className="mt-5 max-w-xl text-lg text-slate-300">
15
+ TanStack Start, Tailwind CSS, and a Bun-powered Turborepo workspace.
16
+ </p>
17
+ </main>
18
+ );
19
+ }
@@ -0,0 +1 @@
1
+ @import "tailwindcss";
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "jsx": "react-jsx",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "types": ["vite/client"]
11
+ },
12
+ "include": ["src", "vite.config.ts"]
13
+ }
@@ -0,0 +1,8 @@
1
+ import tailwindcss from "@tailwindcss/vite";
2
+ import { tanstackStart } from "@tanstack/react-start/plugin/vite";
3
+ import react from "@vitejs/plugin-react";
4
+ import { defineConfig } from "vite";
5
+
6
+ export default defineConfig({
7
+ plugins: [tanstackStart(), react(), tailwindcss()],
8
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "root": false,
3
+ "$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
4
+ "formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
5
+ "linter": { "enabled": true, "rules": { "preset": "recommended" } },
6
+ "javascript": { "formatter": { "quoteStyle": "double" } }
7
+ }
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ dist
3
+ .turbo
4
+ .output
5
+ .tanstack
6
+ .env*
7
+ !.env.example
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "packageManager": "bun@1.3.14",
5
+ "workspaces": [
6
+ "apps/*",
7
+ "packages/*"
8
+ ],
9
+ "scripts": {
10
+ "dev": "turbo run dev",
11
+ "build": "turbo run build",
12
+ "check": "turbo run check"
13
+ },
14
+ "devDependencies": {
15
+ "@biomejs/biome": "2.6.5",
16
+ "turbo": "^2.5.0"
17
+ }
18
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "tasks": {
4
+ "build": {
5
+ "dependsOn": ["^build"],
6
+ "outputs": ["dist/**", ".output/**", ".tanstack/**"]
7
+ },
8
+ "dev": { "cache": false, "persistent": true },
9
+ "check": { "dependsOn": ["^check"] }
10
+ }
11
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.