Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/21st-dev/1code/llms.txt

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

Overview

The Projects router manages project folders, git repository information, and project metadata. Each project represents a local directory that can contain git repositories.

Methods

list

List all projects ordered by most recently updated.
const projects = await trpc.projects.list.query();
Returns: Project[]
id
string
Unique project identifier
name
string
Project name (folder name by default)
path
string
Absolute path to project directory
gitRemoteUrl
string | null
Git remote URL (if repository)
gitProvider
string | null
Git provider: github, gitlab, bitbucket
gitOwner
string | null
Repository owner (GitHub username or org)
gitRepo
string | null
Repository name
iconPath
string | null
Path to custom project icon
createdAt
Date
Project creation timestamp
updatedAt
Date
Last updated timestamp

get

Get a single project by ID.
const project = await trpc.projects.get.query({ id: 'proj_123' });
id
string
required
Project ID
Returns: Project | null

create

Create a project from a known path.
const project = await trpc.projects.create.mutate({
  path: '/Users/username/projects/my-app',
  name: 'My App' // optional
});
path
string
required
Absolute path to project directory
name
string
Custom project name (defaults to folder name)
Returns: Project
If a project with the same path already exists, the existing project is returned.

openFolder

Open a native folder picker dialog and create a project from the selected folder.
const project = await trpc.projects.openFolder.mutate();
Returns: Project | null (null if user cancels)

rename

Rename a project.
const project = await trpc.projects.rename.mutate({
  id: 'proj_123',
  name: 'New Name'
});
id
string
required
Project ID
name
string
required
New project name (min 1 character)
Returns: Project

delete

Delete a project and all its chats.
const deleted = await trpc.projects.delete.mutate({
  id: 'proj_123'
});
id
string
required
Project ID
Returns: Project (deleted project)
This only deletes the project record and associated chats from the database. The actual project folder is not deleted from disk.

refreshGitInfo

Refresh git remote information for a project.
const project = await trpc.projects.refreshGitInfo.mutate({
  id: 'proj_123'
});
id
string
required
Project ID
Returns: Project | null

cloneFromGitHub

Clone a GitHub repository and create a project.
const project = await trpc.projects.cloneFromGitHub.mutate({
  repoUrl: 'https://github.com/owner/repo'
});
repoUrl
string
required
GitHub repository URL (HTTPS, SSH, or short format owner/repo)
Returns: Project Repositories are cloned to ~/.21st/repos/{owner}/{repo}.

locateAndAddProject

Open a folder picker to locate an existing clone of a specific repository.
const result = await trpc.projects.locateAndAddProject.mutate({
  expectedOwner: 'facebook',
  expectedRepo: 'react'
});

if (result.success) {
  console.log('Project added:', result.project);
} else {
  console.log('Failed:', result.reason);
}
expectedOwner
string
required
Expected repository owner
expectedRepo
string
required
Expected repository name
Returns:
| { success: true; project: Project }
| { success: false; reason: 'no-window' | 'canceled' | 'wrong-repo'; found?: string }

pickCloneDestination

Open a folder picker to choose where to clone a repository.
const result = await trpc.projects.pickCloneDestination.mutate({
  suggestedName: 'react'
});

if (result.success) {
  console.log('Clone to:', result.targetPath);
}
suggestedName
string
required
Suggested folder name for the clone
Returns:
| { success: true; targetPath: string }
| { success: false; reason: 'no-window' | 'canceled' }

uploadIcon

Upload a custom icon for a project.
const project = await trpc.projects.uploadIcon.mutate({
  id: 'proj_123'
});
id
string
required
Project ID
Opens a native file picker for image selection. Supported formats: PNG, JPG, JPEG, SVG, WebP, ICO. Returns: Project | null

removeIcon

Remove the custom icon for a project.
const project = await trpc.projects.removeIcon.mutate({
  id: 'proj_123'
});
id
string
required
Project ID
Returns: Project

getLaunchDirectory

Get the directory passed via CLI when launching the app (consumed once).
const path = await trpc.projects.getLaunchDirectory.query();
if (path) {
  console.log('Launched with:', path);
}
Returns: string | null
Based on PR #16 by @caffeinum

Examples

Create project from path

// Check if directory exists first
const fs = require('fs');
const projectPath = '/Users/username/projects/my-app';

if (fs.existsSync(projectPath)) {
  const project = await trpc.projects.create.mutate({
    path: projectPath
  });
  console.log('Project created:', project.id);
}

Clone and open GitHub repo

try {
  const project = await trpc.projects.cloneFromGitHub.mutate({
    repoUrl: 'https://github.com/vercel/next.js'
  });
  
  console.log('Cloned to:', project.path);
  console.log('Remote:', project.gitRemoteUrl);
} catch (error) {
  console.error('Clone failed:', error.message);
}

List projects with git info

const projects = await trpc.projects.list.query();

for (const project of projects) {
  console.log(`${project.name} (${project.path})`);
  
  if (project.gitRemoteUrl) {
    console.log(`  Git: ${project.gitOwner}/${project.gitRepo}`);
  }
}

Build docs developers (and LLMs) love