Vercel Logo

Read Files from the Sandbox

We cloned a repo. Now we should probably look at what we got.

There are two ways to inspect a cloned project from outside the Sandbox: run a shell command and parse the output, or read files directly with the SDK. We're going to do both, because both come in handy.

Outcome

List the cloned repo's contents with ls, read a file with sandbox.readFile, and handle the case where the file you wanted doesn't exist.

Fast Track

  1. Run ls -la repo and log the output.
  2. Read repo/README.md with sandbox.readFile.
  3. Add a fallback so a missing file doesn't crash the script.

Hands-on exercise

Extend src/sandbox-lifecycle.ts after the clone step:

import { Sandbox } from '@vercel/sandbox';
 
const REPO_URL = 'https://github.com/vercel/examples';
 
async function main() {
  const sandbox = await Sandbox.create();
  console.log(`Sandbox created: ${sandbox.sandboxId}`);
 
  const clone = await sandbox.runCommand(`git clone ${REPO_URL} repo`);
  if (clone.exitCode !== 0) {
    console.error(`Clone failed: ${clone.stderr}`);
    await sandbox.stop();
    return;
  }
 
  const ls = await sandbox.runCommand('ls -la repo');
  console.log('--- repo contents ---');
  console.log(ls.stdout);
 
  let readmePreview = '(no README found)';
  try {
    const readme = await sandbox.readFile('repo/README.md');
    readmePreview = readme.slice(0, 300);
  } catch (error) {
    console.warn('Could not read README.md:', error);
  }
 
  console.log('--- README preview ---');
  console.log(readmePreview);
 
  await sandbox.stop();
}
 
main();

Two things to notice. First, we wrapped readFile in try/catch because not every repo has a README at that path. Some use lowercase readme.md, some put docs in a docs/ folder, some don't have one at all. We catch the error, log a warning, and keep going. The Sandbox itself doesn't care about your missing README.

Second, we bailed early on a failed clone. Continuing past a failed clone means everything after it fails for confusing reasons. Fail fast, fail loud.

Troubleshooting: readFile returns empty string

An empty string usually means the file exists but is empty, not that it's missing. A missing file throws. If you're getting empty output, check the file in ls first.

Troubleshooting: path mismatch

readFile('repo/README.md') is case-sensitive on the Sandbox filesystem. If ls shows Readme.md or readme.md, you'll need to match the case exactly.

Try It

pnpm tsx src/sandbox-lifecycle.ts

Expected output:

Sandbox created: sbx_7N2k4A...
--- repo contents ---
total 32
drwxr-xr-x  ... .git
-rw-r--r--  ... README.md
-rw-r--r--  ... package.json
drwxr-xr-x  ... examples
--- README preview ---
# Vercel Examples

This repository contains a set of example projects...

If README.md doesn't exist in the repo you're testing, you'll see (no README found) instead of crashing. That's the point.

Commit

git add src/sandbox-lifecycle.ts
git commit -m "feat(sandbox): list directory and read files from sandbox"

Done-When

  • ls -la repo returns the cloned directory listing
  • sandbox.readFile returns the README contents on a real repo
  • Missing README logs a warning instead of crashing
  • The script still stops the Sandbox at the end

Solution

src/sandbox-lifecycle.ts
import { Sandbox } from '@vercel/sandbox';
 
const REPO_URL = 'https://github.com/vercel/examples';
 
async function main() {
  const sandbox = await Sandbox.create();
  console.log(`Sandbox created: ${sandbox.sandboxId}`);
 
  const clone = await sandbox.runCommand(`git clone ${REPO_URL} repo`);
  if (clone.exitCode !== 0) {
    console.error(`Clone failed: ${clone.stderr}`);
    await sandbox.stop();
    return;
  }
 
  const ls = await sandbox.runCommand('ls -la repo');
  console.log('--- repo contents ---');
  console.log(ls.stdout);
 
  let readmePreview = '(no README found)';
  try {
    const readme = await sandbox.readFile('repo/README.md');
    readmePreview = readme.slice(0, 300);
  } catch (error) {
    console.warn('Could not read README.md:', error);
  }
 
  console.log('--- README preview ---');
  console.log(readmePreview);
 
  await sandbox.stop();
}
 
main();

Was this helpful?

supported.