Rename packages directory to apps for consistent monorepo structure

This commit is contained in:
Aman Varshney
2025-03-24 23:20:14 +05:30
parent 6879491c8b
commit d0133f3b64
92 changed files with 41 additions and 45 deletions

View File

@@ -0,0 +1,5 @@
---
"create-better-t-stack": patch
---
rename packages folder to apps

View File

@@ -87,7 +87,7 @@ async function setupPwa(projectDir: string) {
await fs.copy(pwaTemplateDir, projectDir, { overwrite: true }); await fs.copy(pwaTemplateDir, projectDir, { overwrite: true });
} }
const clientPackageDir = path.join(projectDir, "packages/client"); const clientPackageDir = path.join(projectDir, "apps/client");
addPackageDependency({ addPackageDependency({
dependencies: ["vite-plugin-pwa"], dependencies: ["vite-plugin-pwa"],

View File

@@ -22,8 +22,8 @@ export async function setupAuth(
return; return;
} }
const serverDir = path.join(projectDir, "packages/server"); const serverDir = path.join(projectDir, "apps/server");
const clientDir = path.join(projectDir, "packages/client"); const clientDir = path.join(projectDir, "apps/client");
try { try {
addPackageDependency({ addPackageDependency({

View File

@@ -57,7 +57,7 @@ The API is running at [http://localhost:3000](http://localhost:3000).
\`\`\` \`\`\`
${projectName}/ ${projectName}/
├── packages/ ├── apps/
│ ├── client/ # Frontend application (React, TanStack Router) │ ├── client/ # Frontend application (React, TanStack Router)
│ └── server/ # Backend API (Hono, tRPC) │ └── server/ # Backend API (Hono, tRPC)
\`\`\` \`\`\`
@@ -122,16 +122,16 @@ function generateDatabaseSetup(
1. Start the local SQLite database: 1. Start the local SQLite database:
\`\`\`bash \`\`\`bash
cd packages/server && ${packageManagerRunCmd} db:local cd apps/server && ${packageManagerRunCmd} db:local
\`\`\` \`\`\`
2. Update your \`.env\` file in the \`packages/server\` directory with the appropriate connection details if needed. 2. Update your \`.env\` file in the \`apps/server\` directory with the appropriate connection details if needed.
`; `;
} else if (database === "postgres") { } else if (database === "postgres") {
setup += `This project uses PostgreSQL${orm === "drizzle" ? " with Drizzle ORM" : " with Prisma"}. setup += `This project uses PostgreSQL${orm === "drizzle" ? " with Drizzle ORM" : " with Prisma"}.
1. Make sure you have a PostgreSQL database set up. 1. Make sure you have a PostgreSQL database set up.
2. Update your \`packages/server/.env\` file with your PostgreSQL connection details. 2. Update your \`apps/server/.env\` file with your PostgreSQL connection details.
`; `;
} }
@@ -162,7 +162,7 @@ function generateScriptsList(
- \`${packageManagerRunCmd} build\`: Build both client and server - \`${packageManagerRunCmd} build\`: Build both client and server
- \`${packageManagerRunCmd} dev:client\`: Start only the client - \`${packageManagerRunCmd} dev:client\`: Start only the client
- \`${packageManagerRunCmd} dev:server\`: Start only the server - \`${packageManagerRunCmd} dev:server\`: Start only the server
- \`${packageManagerRunCmd} check-types\`: Check TypeScript types across all packages`; - \`${packageManagerRunCmd} check-types\`: Check TypeScript types across all apps`;
if (database !== "none") { if (database !== "none") {
scripts += ` scripts += `
@@ -170,7 +170,7 @@ function generateScriptsList(
- \`${packageManagerRunCmd} db:studio\`: Open database studio UI`; - \`${packageManagerRunCmd} db:studio\`: Open database studio UI`;
if (database === "sqlite" && orm === "drizzle") { if (database === "sqlite" && orm === "drizzle") {
scripts += `\n- \`cd packages/server && ${packageManagerRunCmd} db:local\`: Start the local SQLite database`; scripts += `\n- \`cd apps/server && ${packageManagerRunCmd} db:local\`: Start the local SQLite database`;
} }
} }

View File

@@ -13,7 +13,7 @@ export async function setupDatabase(
setupTursoDb = true, setupTursoDb = true,
): Promise<void> { ): Promise<void> {
const s = spinner(); const s = spinner();
const serverDir = path.join(projectDir, "packages/server"); const serverDir = path.join(projectDir, "apps/server");
if (databaseType === "none") { if (databaseType === "none") {
await fs.remove(path.join(serverDir, "src/db")); await fs.remove(path.join(serverDir, "src/db"));

View File

@@ -7,8 +7,8 @@ export async function setupEnvironmentVariables(
projectDir: string, projectDir: string,
options: ProjectConfig, options: ProjectConfig,
): Promise<void> { ): Promise<void> {
const serverDir = path.join(projectDir, "packages/server"); const serverDir = path.join(projectDir, "apps/server");
const clientDir = path.join(projectDir, "packages/client"); const clientDir = path.join(projectDir, "apps/client");
const envPath = path.join(serverDir, ".env"); const envPath = path.join(serverDir, ".env");
let envContent = ""; let envContent = "";

View File

@@ -23,21 +23,18 @@ async function setupTodoExample(
): Promise<void> { ): Promise<void> {
const todoExampleDir = path.join(PKG_ROOT, "template/examples/todo"); const todoExampleDir = path.join(PKG_ROOT, "template/examples/todo");
if (await fs.pathExists(todoExampleDir)) { if (await fs.pathExists(todoExampleDir)) {
const todoRouteDir = path.join( const todoRouteDir = path.join(todoExampleDir, "apps/client/src/routes");
todoExampleDir, const targetRouteDir = path.join(projectDir, "apps/client/src/routes");
"packages/client/src/routes",
);
const targetRouteDir = path.join(projectDir, "packages/client/src/routes");
await fs.copy(todoRouteDir, targetRouteDir, { overwrite: true }); await fs.copy(todoRouteDir, targetRouteDir, { overwrite: true });
if (orm !== "none") { if (orm !== "none") {
const todoRouterSourceFile = path.join( const todoRouterSourceFile = path.join(
todoExampleDir, todoExampleDir,
`packages/server/src/routers/with-${orm}-todo.ts`, `apps/server/src/routers/with-${orm}-todo.ts`,
); );
const todoRouterTargetFile = path.join( const todoRouterTargetFile = path.join(
projectDir, projectDir,
"packages/server/src/routers/todo.ts", "apps/server/src/routers/todo.ts",
); );
if (await fs.pathExists(todoRouterSourceFile)) { if (await fs.pathExists(todoRouterSourceFile)) {
@@ -58,7 +55,7 @@ async function updateHeaderWithTodoLink(
): Promise<void> { ): Promise<void> {
const headerPath = path.join( const headerPath = path.join(
projectDir, projectDir,
"packages/client/src/components/header.tsx", "apps/client/src/components/header.tsx",
); );
if (await fs.pathExists(headerPath)) { if (await fs.pathExists(headerPath)) {
@@ -87,7 +84,7 @@ async function cleanupTodoFiles(
if (orm === "drizzle") { if (orm === "drizzle") {
const todoSchemaFile = path.join( const todoSchemaFile = path.join(
projectDir, projectDir,
"packages/server/src/db/schema/todo.ts", "apps/server/src/db/schema/todo.ts",
); );
if (await fs.pathExists(todoSchemaFile)) { if (await fs.pathExists(todoSchemaFile)) {
await fs.remove(todoSchemaFile); await fs.remove(todoSchemaFile);
@@ -95,7 +92,7 @@ async function cleanupTodoFiles(
} else if (orm === "prisma") { } else if (orm === "prisma") {
const todoPrismaFile = path.join( const todoPrismaFile = path.join(
projectDir, projectDir,
"packages/server/prisma/schema/todo.prisma", "apps/server/prisma/schema/todo.prisma",
); );
if (await fs.pathExists(todoPrismaFile)) { if (await fs.pathExists(todoPrismaFile)) {
await fs.remove(todoPrismaFile); await fs.remove(todoPrismaFile);
@@ -104,7 +101,7 @@ async function cleanupTodoFiles(
const todoRouterFile = path.join( const todoRouterFile = path.join(
projectDir, projectDir,
"packages/server/src/routers/todo.ts", "apps/server/src/routers/todo.ts",
); );
if (await fs.pathExists(todoRouterFile)) { if (await fs.pathExists(todoRouterFile)) {
await fs.remove(todoRouterFile); await fs.remove(todoRouterFile);
@@ -114,10 +111,7 @@ async function cleanupTodoFiles(
} }
async function updateRouterIndex(projectDir: string): Promise<void> { async function updateRouterIndex(projectDir: string): Promise<void> {
const routerFile = path.join( const routerFile = path.join(projectDir, "apps/server/src/routers/index.ts");
projectDir,
"packages/server/src/routers/index.ts",
);
if (await fs.pathExists(routerFile)) { if (await fs.pathExists(routerFile)) {
let routerContent = await fs.readFile(routerFile, "utf8"); let routerContent = await fs.readFile(routerFile, "utf8");
@@ -131,10 +125,7 @@ async function updateRouterIndex(projectDir: string): Promise<void> {
} }
async function addTodoButtonToHomepage(projectDir: string): Promise<void> { async function addTodoButtonToHomepage(projectDir: string): Promise<void> {
const indexPath = path.join( const indexPath = path.join(projectDir, "apps/client/src/routes/index.tsx");
projectDir,
"packages/client/src/routes/index.tsx",
);
if (await fs.pathExists(indexPath)) { if (await fs.pathExists(indexPath)) {
let indexContent = await fs.readFile(indexPath, "utf8"); let indexContent = await fs.readFile(indexPath, "utf8");

View File

@@ -68,7 +68,7 @@ function getDatabaseInstructions(
} else if (orm === "drizzle") { } else if (orm === "drizzle") {
if (database === "sqlite") { if (database === "sqlite") {
instructions.push( instructions.push(
`${pc.cyan("•")} Start local DB: ${pc.dim(`cd packages/server && ${runCmd} db:local`)}`, `${pc.cyan("•")} Start local DB: ${pc.dim(`cd apps/server && ${runCmd} db:local`)}`,
); );
} }
instructions.push( instructions.push(
@@ -85,5 +85,5 @@ function getDatabaseInstructions(
} }
function getTauriInstructions(runCmd?: string): string { function getTauriInstructions(runCmd?: string): string {
return `${pc.bold("Desktop app with Tauri:")}\n${pc.cyan("•")} Start desktop app: ${pc.dim(`cd packages/client && ${runCmd} desktop:dev`)}\n${pc.cyan("•")} Build desktop app: ${pc.dim(`cd packages/client && ${runCmd} desktop:build`)}\n${pc.yellow("NOTE:")} Tauri requires Rust and platform-specific dependencies. See: ${pc.dim("https://v2.tauri.app/start/prerequisites/")}\n\n`; return `${pc.bold("Desktop app with Tauri:")}\n${pc.cyan("•")} Start desktop app: ${pc.dim(`cd apps/client && ${runCmd} desktop:dev`)}\n${pc.cyan("•")} Build desktop app: ${pc.dim(`cd apps/client && ${runCmd} desktop:build`)}\n${pc.yellow("NOTE:")} Tauri requires Rust and platform-specific dependencies. See: ${pc.dim("https://v2.tauri.app/start/prerequisites/")}\n\n`;
} }

View File

@@ -52,7 +52,7 @@ async function updateServerPackageJson(
): Promise<void> { ): Promise<void> {
const serverPackageJsonPath = path.join( const serverPackageJsonPath = path.join(
projectDir, projectDir,
"packages/server/package.json", "apps/server/package.json",
); );
if (await fs.pathExists(serverPackageJsonPath)) { if (await fs.pathExists(serverPackageJsonPath)) {

View File

@@ -11,7 +11,7 @@ export async function setupTauri(
packageManager: PackageManager, packageManager: PackageManager,
): Promise<void> { ): Promise<void> {
const s = spinner(); const s = spinner();
const clientPackageDir = path.join(projectDir, "packages/client"); const clientPackageDir = path.join(projectDir, "apps/client");
try { try {
s.start("Setting up Tauri desktop app support..."); s.start("Setting up Tauri desktop app support...");

View File

@@ -36,7 +36,7 @@ export async function setupOrmTemplate(
if (await fs.pathExists(ormTemplateDir)) { if (await fs.pathExists(ormTemplateDir)) {
await fs.copy(ormTemplateDir, projectDir, { overwrite: true }); await fs.copy(ormTemplateDir, projectDir, { overwrite: true });
const serverSrcPath = path.join(projectDir, "packages/server/src"); const serverSrcPath = path.join(projectDir, "apps/server/src");
const libPath = path.join(serverSrcPath, "lib"); const libPath = path.join(serverSrcPath, "lib");
const withAuthLibPath = path.join(serverSrcPath, "with-auth-lib"); const withAuthLibPath = path.join(serverSrcPath, "with-auth-lib");
@@ -54,8 +54,8 @@ export async function setupOrmTemplate(
export async function fixGitignoreFiles(projectDir: string): Promise<void> { export async function fixGitignoreFiles(projectDir: string): Promise<void> {
const gitignorePaths = [ const gitignorePaths = [
path.join(projectDir, "_gitignore"), path.join(projectDir, "_gitignore"),
path.join(projectDir, "packages/client/_gitignore"), path.join(projectDir, "apps/client/_gitignore"),
path.join(projectDir, "packages/server/_gitignore"), path.join(projectDir, "apps/server/_gitignore"),
]; ];
for (const gitignorePath of gitignorePaths) { for (const gitignorePath of gitignorePaths) {

View File

@@ -159,7 +159,7 @@ async function createTursoDatabase(
} }
async function writeEnvFile(projectDir: string, config?: TursoConfig) { async function writeEnvFile(projectDir: string, config?: TursoConfig) {
const envPath = path.join(projectDir, "packages/server", ".env"); const envPath = path.join(projectDir, "apps/server", ".env");
const envContent = config const envContent = config
? `TURSO_CONNECTION_URL="${config.dbUrl}" ? `TURSO_CONNECTION_URL="${config.dbUrl}"
TURSO_AUTH_TOKEN="${config.authToken}"` TURSO_AUTH_TOKEN="${config.authToken}"`
@@ -175,7 +175,7 @@ function displayManualSetupInstructions() {
1. Visit https://turso.tech and create an account 1. Visit https://turso.tech and create an account
2. Create a new database from the dashboard 2. Create a new database from the dashboard
3. Get your database URL and authentication token 3. Get your database URL and authentication token
4. Add these credentials to the .env file in packages/server/.env 4. Add these credentials to the .env file in apps/server/.env
TURSO_CONNECTION_URL=your_database_url TURSO_CONNECTION_URL=your_database_url
TURSO_AUTH_TOKEN=your_auth_token`); TURSO_AUTH_TOKEN=your_auth_token`);

View File

@@ -11,8 +11,10 @@
"check-types": "tsc --noEmit" "check-types": "tsc --noEmit"
}, },
"devDependencies": { "devDependencies": {
"@tanstack/react-query-devtools": "^5.69.0",
"@tanstack/react-router-devtools": "^1.114.27",
"@tanstack/router-plugin": "^1.114.27", "@tanstack/router-plugin": "^1.114.27",
"@types/node": "^22.13.11", "@types/node": "^22.13.13",
"@types/react": "^19.0.12", "@types/react": "^19.0.12",
"@types/react-dom": "^19.0.4", "@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4", "@vitejs/plugin-react": "^4.3.4",
@@ -29,9 +31,7 @@
"@tanstack/react-form": "^1.0.5", "@tanstack/react-form": "^1.0.5",
"@tailwindcss/vite": "^4.0.15", "@tailwindcss/vite": "^4.0.15",
"@tanstack/react-query": "^5.69.0", "@tanstack/react-query": "^5.69.0",
"@tanstack/react-query-devtools": "^5.69.0",
"@tanstack/react-router": "^1.114.25", "@tanstack/react-router": "^1.114.25",
"@tanstack/router-devtools": "^1.114.25",
"@trpc/client": "^11.0.0", "@trpc/client": "^11.0.0",
"@trpc/react-query": "^11.0.0", "@trpc/react-query": "^11.0.0",
"@trpc/server": "^11.0.0", "@trpc/server": "^11.0.0",

View File

@@ -1,7 +1,7 @@
{ {
"name": "better-t-stack", "name": "better-t-stack",
"private": true, "private": true,
"workspaces": ["packages/*"], "workspaces": ["apps/*"],
"scripts": { "scripts": {
"dev": "turbo dev", "dev": "turbo dev",
"build": "turbo build", "build": "turbo build",

View File

@@ -1,2 +1,2 @@
packages: packages:
- "packages/*" - "apps/*"

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB