Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/amanvarshney01/create-better-t-stack/llms.txt

Use this file to discover all available pages before exploring further.

The createVirtual() function generates a project in-memory using a virtual filesystem. This is useful for web previews, testing, and analysis without disk I/O.

Signature

function createVirtual(
  options: Partial<Omit<ProjectConfig, "projectDir" | "relativePath">>
): Promise<Result<VirtualFileTree, GeneratorError>>
Source: ~/workspace/source/apps/cli/src/index.ts:287

Parameters

options
Partial<ProjectConfig>
required
Project configuration options. Subset of CreateInput without file system paths.

Return Type

Promise<Result<VirtualFileTree, GeneratorError>>

Success (Result.ok)

Returns VirtualFileTree:
root
VirtualDirectory
required
Root directory node of the virtual file tree.
interface VirtualDirectory {
  type: "directory";
  path: string;
  name: string;
  children: VirtualNode[];
}
fileCount
number
required
Total number of files in the virtual tree.Example: 42
directoryCount
number
required
Total number of directories in the virtual tree.Example: 12
config
ProjectConfig
required
The complete project configuration used for generation.

Error (Result.err)

Returns GeneratorError:
class GeneratorError {
  tag: "GeneratorError";
  message: string;
  phase?: string;
  cause?: unknown;
}
See Error Handling for details.

Examples

Basic Usage

import { createVirtual } from "create-better-t-stack";

const result = await createVirtual({
  frontend: ["tanstack-router"],
  backend: "hono",
  database: "sqlite",
  orm: "drizzle",
});

result.match({
  ok: (tree) => {
    console.log(`Generated ${tree.fileCount} files`);
    console.log(`Root: ${tree.root.name}`);
  },
  err: (error) => {
    console.error(`Failed: ${error.message}`);
  },
});

Walking the File Tree

import { createVirtual } from "create-better-t-stack";

const result = await createVirtual({
  projectName: "my-app",
  frontend: ["next"],
  backend: "hono",
});

if (result.isOk()) {
  const tree = result.value;
  
  function walkTree(node, depth = 0) {
    const indent = "  ".repeat(depth);
    
    if (node.type === "directory") {
      console.log(`${indent}📁 ${node.name}/`);
      for (const child of node.children) {
        walkTree(child, depth + 1);
      }
    } else {
      console.log(`${indent}📄 ${node.name}`);
    }
  }
  
  walkTree(tree.root);
}

Reading File Contents

import { createVirtual, type VirtualNode } from "create-better-t-stack";

const result = await createVirtual({
  frontend: ["tanstack-router"],
  backend: "hono",
});

if (result.isOk()) {
  const tree = result.value;
  
  function findFile(node: VirtualNode, name: string): VirtualFile | null {
    if (node.type === "file" && node.name === name) {
      return node;
    }
    if (node.type === "directory") {
      for (const child of node.children) {
        const found = findFile(child, name);
        if (found) return found;
      }
    }
    return null;
  }
  
  const packageJson = findFile(tree.root, "package.json");
  if (packageJson) {
    const pkg = JSON.parse(packageJson.content);
    console.log(`Project: ${pkg.name}`);
    console.log(`Dependencies:`, pkg.dependencies);
  }
}

Web Preview Use Case

import { createVirtual, EMBEDDED_TEMPLATES } from "create-better-t-stack";
import express from "express";

const app = express();

app.post("/api/generate", async (req, res) => {
  const result = await createVirtual({
    projectName: req.body.projectName,
    frontend: req.body.frontend,
    backend: req.body.backend,
    database: req.body.database,
    orm: req.body.orm,
  });
  
  result.match({
    ok: (tree) => {
      res.json({
        success: true,
        fileCount: tree.fileCount,
        files: tree.root,
      });
    },
    err: (error) => {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    },
  });
});

app.listen(3000);

Testing Configuration

import { describe, expect, test } from "bun:test";
import { createVirtual } from "create-better-t-stack";

describe("Project Generation", () => {
  test("generates with Drizzle ORM", async () => {
    const result = await createVirtual({
      database: "postgres",
      orm: "drizzle",
    });
    
    expect(result.isOk()).toBe(true);
    
    if (result.isOk()) {
      const tree = result.value;
      
      // Check for Drizzle config
      function hasFile(node, name) {
        if (node.type === "file" && node.name === name) return true;
        if (node.type === "directory") {
          return node.children.some(child => hasFile(child, name));
        }
        return false;
      }
      
      expect(hasFile(tree.root, "drizzle.config.ts")).toBe(true);
    }
  });
});

Analyzing Generated Files

import { createVirtual } from "create-better-t-stack";

const result = await createVirtual({
  frontend: ["tanstack-router"],
  backend: "hono",
  database: "postgres",
  orm: "drizzle",
  auth: "better-auth",
});

if (result.isOk()) {
  const tree = result.value;
  
  const stats = {
    totalFiles: tree.fileCount,
    totalDirs: tree.directoryCount,
    fileTypes: new Map<string, number>(),
  };
  
  function analyzeNode(node) {
    if (node.type === "file") {
      const ext = node.extension || "no-ext";
      stats.fileTypes.set(ext, (stats.fileTypes.get(ext) || 0) + 1);
    } else {
      node.children.forEach(analyzeNode);
    }
  }
  
  analyzeNode(tree.root);
  
  console.log(`Files: ${stats.totalFiles}`);
  console.log(`Directories: ${stats.totalDirs}`);
  console.log(`File types:`, Object.fromEntries(stats.fileTypes));
}

Use Cases

Web Previews

Generate and display project structure in web UIs without disk access

Testing

Test project generation in unit tests without filesystem I/O

Analysis

Analyze generated files and dependencies programmatically

Documentation

Generate example projects for documentation

Virtual File Tree Structure

The returned VirtualFileTree has this structure:
interface VirtualFileTree {
  root: VirtualDirectory;
  fileCount: number;
  directoryCount: number;
  config: ProjectConfig;
}

interface VirtualDirectory {
  type: "directory";
  path: string;        // "src/components"
  name: string;        // "components"
  children: VirtualNode[];
}

interface VirtualFile {
  type: "file";
  path: string;        // "src/index.ts"
  name: string;        // "index.ts"
  content: string;     // File contents
  extension: string;   // "ts"
  sourcePath?: string; // Original template path
}

type VirtualNode = VirtualFile | VirtualDirectory;

Notes

createVirtual() uses the same template engine as create(), but outputs to an in-memory filesystem instead of disk.
The virtual filesystem is powered by memfs and supports all standard file operations.

Build docs developers (and LLMs) love