Terminal Shortcut for macOS iTerm: Launch Your Dev Environment with One Command

Spinning up a full stack project usually means opening terminals, cd-ing into folders, killing ports, running servers, maybe opening VS Code… every. single. time.

This shortcut wraps all of that into one command: it opens iTerm, creates labeled tabs for each service (backend, frontend, ngrok, etc.), kills any lingering processes on the right ports, starts everything, and (optionally) opens the folder in VS Code.

What you’ll build

dev-insyte
# or, to auto-open VS Code on each tab's directory:
dev-insyte --open-vs-code

The script

✅ Copy this into ~/.scripts/dev-insyte

🔒 Replace any secret values with your own secure env handling (see notes below)

#!/bin/bash
OPEN_VSCODE=false

# Parse flags
for arg in "$@"; do
  if [ "$arg" = "--open-vs-code" ]; then
    OPEN_VSCODE=true
  fi
done

# Define function to append "code ." if flag is present
append_code_command() {
  local dir="$1"
  if $OPEN_VSCODE; then
    echo "cd $dir && code ."
  else
    echo "cd $dir"
  fi
}

osascript <<'EOF'
tell application "iTerm"
    activate
    set newWindow to (create window with default profile)

    -- Tab 1: Flowise (example service)
    tell current session of newWindow
        set name to "Flowise"
        write text "echo -ne '\\033]0;Flowise\\007';"
        write text "lsof -ti:3001 | xargs kill -9;"
        write text "STORAGE_TYPE=s3 S3_STORAGE_BUCKET_NAME=<YOUR_BUCKET> S3_STORAGE_ACCESS_KEY_ID=<YOUR_KEY_ID> S3_STORAGE_SECRET_ACCESS_KEY=<YOUR_SECRET> S3_STORAGE_REGION=ap-southeast-1 PORT=3001 flowise start;"
    end tell

    -- Tab 2: Backend
    tell newWindow
        set backendTab to (create tab with default profile)
        tell current session of backendTab
            set name to "Backend"
            write text "echo -ne '\\033]0;Backend\\007';"
            write text "$(append_code_command "/Users/dia/dev/projects/insyte/insyte-be")"
            write text "lsof -ti:3000 | xargs kill -9; cd /Users/dia/dev/projects/insyte/insyte-be && npm run start:dev"
        end tell
    end tell

    -- Tab 3: Frontend
    tell newWindow
        set frontendTab to (create tab with default profile)
        tell current session of frontendTab
            set name to "Frontend"
            write text "echo -ne '\\033]0;Frontend\\007';"
            write text "$(append_code_command "/Users/dia/dev/projects/insyte/insyte-fe")"
            write text "lsof -ti:5173 | xargs kill -9; cd /Users/dia/dev/projects/insyte/insyte-fe && npm run dev"
        end tell
    end tell

    -- Tab 4: ngrok
    tell newWindow
        set webhookTab to (create tab with default profile)
        tell current session of webhookTab
            set name to "ngrok"
            write text "echo -ne '\\033]0;ngrok\\007';"
            write text "ngrok http 3000 --domain=devacademe.ngrok.dev"
        end tell
    end tell
end tell
EOF

Make it executable and add a shortcut

chmod +x ~/.scripts/dev-insyte

In your shell config (~/.zshrc or ~/.bashrc):

alias dev-insyte=~/.scripts/dev-insyte

Reload your shell:

source ~/.zshrc   # or ~/.bashrc

How it works (line-by-line tour)

1) Flag parsing: --open-vs-code

OPEN_VSCODE=false

for arg in "$@"; do
  if [ "$arg" = "--open-vs-code" ]; then
    OPEN_VSCODE=true
  fi
done
  • Looks for --open-vs-code in the command you run.

  • If present, the script will open VS Code in the relevant tab’s directory.

2) Smart “cd” helper

append_code_command() {
  local dir="$1"
  if $OPEN_VSCODE; then
    echo "cd $dir && code ."
  else
    echo "cd $dir"
  fi
}
  • Returns a string you can inject into iTerm that either:

    • just cds into the folder, or

    • cds and launches VS Code (code .) if the flag is set.

3) Talking to iTerm via AppleScript

osascript <<'EOF'
# ... AppleScript ...
EOF
  • osascript executes AppleScript.

  • The here-doc (<<'EOF') keeps the script contents intact and avoids Bash expanding special characters inside.

4) Create a new iTerm window

tell application "iTerm"
  activate
  set newWindow to (create window with default profile)
  • Brings iTerm to front and opens a window using your default profile.

5) Each tab = one service

Inside each tab you see:

Set the tab title in the iTerm UI

echo -ne '\033]0;Flowise\007'
  • That escape sequence updates the terminal title to “Flowise” (or “Backend”, “Frontend”, etc.).

Kill whatever already uses the port (optional but useful)

lsof -ti:3001 | xargs kill -9
  • lsof -ti:PORT finds PIDs bound to the port.

  • xargs kill -9 force-kills them so your server can bind.

    ⚠️ Be careful: this kills any process on that port.

Export env + start the process

STORAGE_TYPE=s3 S3_STORAGE_BUCKET_NAME=... PORT=3001 flowise start
  • Sets environment variables for this command only.

  • Starts the service (flowise start in this example).

Navigate + run your script

$(append_code_command "/path/to/project")
lsof -ti:3000 | xargs kill -9; cd /path/to/project && npm run start:dev
  • Jumps to the project folder (and opens VS Code if --open-vs-code was used).

  • Kills the port, then starts your dev server.

Open tunnels

ngrok http 3000 --domain=devacademe.ngrok.dev
  • Exposes your local backend to the internet for webhooks or teammates.

6) Tab overview in this setup

  • Tab 1: Flowise — starts Flowise on port 3001 with S3-style env.

  • Tab 2: Backend — npm run start:dev on 3000.

  • Tab 3: Frontend — Vite dev server on 5173.

  • Tab 4: ngrok — tunnels 3000 to a custom domain.

Using it

Basic:

dev-insyte

Open VS Code in backend/frontend tabs automatically:

dev-insyte --open-vs-code

Customize it for your project

  • Change paths:

    • Replace /Users/dia/dev/projects/insyte/insyte-be and insyte-fe with your folders.
  • Change ports:

    • Update 3000, 3001, 5173 to match your services.
  • Change commands:

    • Swap npm run start:dev with pnpm dev, bun dev, docker compose up, etc.
  • Add/Remove tabs:

    • Duplicate a tab block to add Redis, database UI, worker queues, etc.

Summary

You now have a one-liner that:

  • Opens iTerm with labeled tabs,

  • Jumps into the right folders (and optionally opens VS Code),

  • Frees busy ports,

  • Boots all your dev services and a public tunnel.

It’s a tiny quality-of-life improvement that adds up every single day. Happy shipping! 🚀

0
Subscribe to my newsletter

Read articles from Bret Axl Sebastian Pura directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Bret Axl Sebastian Pura
Bret Axl Sebastian Pura