Category: Tools

  • What it takes to actually run NanoClaw

    NanoClaw is the structurally right framework for pipeline-shaped agent workloads. It’s also genuinely more technical to set up than most personal-assistant frameworks people compare it to. If you’re evaluating it after reading the comparison piece and wondering what you’re signing up for, this is the honest answer.

    One thing worth setting up front: NanoClaw is not built for non-technical users, and neither is openclaw despite its more polished onboarding. The marketing on both sites pitches “personal AI assistant for everyone.” The reality is different. NanoClaw expects comfort with git, the command line, Docker, and at least basic Linux administration. The trade you make in exchange is access to Claude Code as the authoring layer for your fork — which is arguably the most capable AI coding tool available right now, and meaningfully more capable than the typical models you’d be running underneath openclaw. The framework is built around that capability difference rather than trying to abstract it away.

    The architecture is right. The setup curve is real. Below is what actually bites.

    You need a Claude Code subscription

    This isn’t a soft dependency. NanoClaw is built around Claude Code as the authoring layer — the slash commands that install channels and providers (/add-telegram, /add-opencode, /add-codex and so on) run inside Claude Code and copy source files into your fork from long-lived branches. You can technically edit the same files by hand, but you’d be reverse-engineering what those slash commands do every time you customise.

    Practically: a Claude Code Pro or Max subscription is the working assumption. Without it, you’re not really running NanoClaw the way it’s designed to run. With it, the authoring experience is the best part of the framework — the codebase is small enough that Claude Code can confidently make changes across it, and the fork-as-install model means every customization is a code change you can read and revert.

    This also constrains who NanoClaw is for. If you’re allergic to Claude Code (philosophically, financially, or because you prefer Codex or another harness as your primary), you’ll fight the framework. If you’re already deep in Claude Code, the integration is genuinely tight.

    Codex works as a fallback authoring layer for individual tasks, and the /add-codex skill makes Codex available as an agent provider (separate from authoring). But the slash-command-based setup expects Claude Code as the primary harness. Plan around that.

    OneCLI is part of the deal

    NanoClaw doesn’t manage your API keys directly. That job is delegated to OneCLI, the companion credential proxy that ships alongside it. Agents inside containers never see raw API keys; they make outbound HTTPS requests through OneCLI, which injects credentials at the proxy layer based on per-agent policies.

    This matters in practice for two reasons. First, agents inside NanoClaw containers have bash access — anything that put an API key directly in the container would be reachable by any code the agent runs. OneCLI keeps that surface clean. Second, you’ll spend real time during setup configuring OneCLI: registering your Anthropic credential, creating per-agent secret assignments, deciding whether each agent gets all secrets or a specific subset. The nanoclaw.sh install script handles the basics, but ongoing changes (adding a new provider, rotating keys, scoping a credential to one agent) involve OneCLI commands rather than editing config files.

    It’s worth understanding before you start. Treat OneCLI as a meaningful piece of the system, not a one-time setup chore that disappears after install.

    There’s no web UI out of the box

    NanoClaw ships the channel and agent runtime. It doesn’t ship an operator console. There’s no dashboard for browsing agent activity, no log viewer, no chat history UI, no admin panel, no menubar app. The framework’s stance is that you talk to your agent through a messaging channel — Telegram, Slack, Discord, WhatsApp, whatever you’ve installed — and that’s the interface.

    Openclaw, by comparison, has a guided openclaw onboard CLI for setup and a Companion App (Beta) on macOS that adds a menubar interface. So if you’re coming from openclaw expecting some kind of UI affordance out of the box, NanoClaw will feel deliberately bare.

    For an assistant, the chat-channel-only approach is fine. The channel is the interface.

    For a pipeline, it’s not enough. Pipelines need state-of-everything views: which prospects are in which stages, which agents are working on what, what’s pending operator review, what’s been dead-lettered. None of that is conversational. You need a UI.

    The options are real but each has a cost:

    Build a custom web UI as a NanoClaw skill. A small Express or similar server inside a skill that exposes a chat-plus-dashboard interface, talks to the agent through the same task contract NanoClaw uses elsewhere, and serves over tailscale serve so it’s only reachable on your tailnet. Takes a day to build. You control the UX completely. You can mount per-agent dashboards next to the chat thread. No third party between you and your operator interface. This is the version I keep coming back to.

    Use a messaging channel as the operator interface. Telegram is fastest to bring up — bot via BotFather, token in five minutes. Discord and Slack work too. The trade is that pipeline state is awkward to display in a chat thread, and you end up either composing structured messages (clunky) or building dashboards anyway (defeats the purpose).

    Lean on the underlying systems for state visibility. SQLite for the artifact and journal storage means you can run ad-hoc queries against it. docker logs for container-level activity. journalctl --user for systemd-level service logs. This works for debugging and post-hoc analysis. It doesn’t work as a real-time operator surface.

    In practice, you’ll mix all three. The custom web UI is the primary operator console, channels handle quick-access from your phone, and you use the underlying tooling when something goes weird and you need to dig.

    Setup gotchas on a small VPS

    NanoClaw runs comfortably on a 2GB DigitalOcean droplet (or equivalent). The hosting cost is a few dollars a month. The friction comes from minimal cloud images being stripped down enough that several setup steps fail in non-obvious ways.

    The base image doesn’t ship with a C compiler. Several modules in the dependency tree build native bindings during pnpm install and fail with generic “command failed” errors that don’t tell you the compiler is missing. Install build tools before the first install:

    sudo apt update
    sudo apt install -y build-essential acl

    The acl package is also missing from minimal images and you’ll need it for the Docker socket fix below.

    The Docker socket ACL doesn’t survive reboot. NanoClaw runs agent containers via Docker. By default, only root can talk to the Docker socket. Adding your operator user to the docker group works but is broadly equivalent to giving that user root, which is not what you want.

    The cleaner approach is an ACL grant on /var/run/docker.sock. The catch: /var/run is a tmpfs mount, recreated on every boot. Anything you setfacl once is wiped on reboot. The fix is a tmpfiles.d rule that recreates the ACL automatically. Create /etc/tmpfiles.d/docker.conf with:

    a+ /var/run/docker.sock - - - - u:youruser:rw

    Replace youruser with the actual operator username. Test with sudo systemd-tmpfiles --create and verify with getfacl /var/run/docker.sock. Reboots no longer break Docker access for the operator account.

    Two systemd services, not one. Run NanoClaw and your custom orchestrator as separate systemd user services. When you’re iterating on the orchestrator (which you will, often, especially in early development), restarting it shouldn’t take the channel adapters down. Channel reconnects are slow and annoying; orchestrator restarts should be near-instant.

    A reasonable layout:

    ~/.config/systemd/user/nanoclaw.service
    ~/.config/systemd/user/orchestrator.service

    If you want either service to start on boot before you log in, enable lingering for the user with sudo loginctl enable-linger youruser. Easy to forget; non-obvious failure mode (services don’t start, you don’t know why, you log in, they magically work).

    Add swap. A 2GB droplet doesn’t ship with swap configured. Under heavy LLM-context loads — long-context windows plus large augmentation tasks — you can OOM unexpectedly. A 2GB swap file is cheap insurance:

    sudo fallocate -l 2G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

    Set vm.swappiness=10 in /etc/sysctl.conf so the kernel prefers RAM and only swaps under genuine pressure. Reboot to verify.

    What stays on the laptop, what goes on the VPS

    The local-versus-VPS question resolves cleanly:

    • A laptop is fine for the install rehearsal, fork setup, and a couple of agents you only use while at the keyboard.
    • Anything that needs to be reachable, scheduled, or running while you’re not at the keyboard belongs on the VPS.

    The cost difference between 1GB and 2GB on DigitalOcean is a few dollars a month, and the difference in headroom is between fighting the host and forgetting about it. Take the 2GB. The marginal saving on a 1GB droplet is not worth the time you’ll spend wondering why builds are failing or why the agent container is OOM’ing.

    Honest scope of “easy”

    NanoClaw is technically simpler than openclaw — fewer lines of code, fewer abstractions, fewer hidden behaviours. It’s not operationally simpler. The framework expects you to:

    • Have a Claude Code subscription and use it as the authoring layer
    • Be comfortable with the Linux command line, systemd, Docker, git
    • Build your own operator UI if you want one
    • Write your own orchestrator if you’re doing pipeline-shaped work

    For someone who already operates in this stack, NanoClaw feels light and clean — and the Claude Code authoring layer is genuinely the best part. The codebase is small enough that asking Claude Code to make changes across it works reliably, which is a meaningfully better experience than the typical “edit config files, hope you got it right, debug when you didn’t” pattern.

    For someone hoping for a one-click personal assistant, the curve is meaningfully steeper than openclaw’s onboarding. Openclaw has a guided CLI (openclaw onboard) and a macOS Companion App that gives you a menubar interface; NanoClaw deliberately ships none of that. Both still expect a technical user underneath, but openclaw lowers the floor more.

    The trade is real and the trade is good if your use case justifies it. You end up with a system you understand end to end, that runs in resources you control, that doesn’t depend on a SaaS gateway, and that you can reason about when something breaks. Worth the lift if you’re building something pipeline-shaped. Not worth the lift if you just want a chatbot.

    A useful concrete reference point: Singapore’s Foreign Minister, Vivian Balakrishnan, published the architecture for his own NanoClaw-based “second brain” setup, with an accompanying X post walking through the composition. He’s technically literate — coding is a known hobby of his — but not a software engineer by trade. His setup composes NanoClaw with a few other open-source pieces (a memory layer, OneCLI for credentials, the LLM Wiki pattern for knowledge synthesis) and runs on a Raspberry Pi. It’s a useful existence proof of “technical-but-not-developer” being the floor for NanoClaw, and equally a useful caution: Vivian could compose those pieces because of fluency he already had. Anyone reading this without that fluency yet would need to pick it up first. The reward is real, and so is the prerequisite.

    The full GTM system this deployment serves is in Building a GTM dark factory with Nemotron 3 and NanoClaw. The framework comparison that motivates picking NanoClaw in the first place is in Why I picked NanoClaw over openclaw for a GTM pipeline.

  • Why I picked NanoClaw over OpenClaw for a GTM pipeline

    Before getting into the comparison itself, one piece of context worth setting straight: neither OpenClaw nor NanoClaw is built for a non-technical audience. Both expect comfort with the command line, git, and at least one model provider’s API setup. Both reward fluency with the underlying stack. The marketing copy on both sites pitches “personal AI assistant for everyone,” which is aspirational. The reality today is that you need to know what pnpm install does and roughly what a Docker container is to get either one running smoothly.

    That said, the two frameworks make different trade-offs within that technical-user space, and which trade-off is right for you depends on what you’re actually building.

    OpenClaw is the more monolithic, more featureful option. It ships a guided CLI onboarding (openclaw onboard), supports multiple LLM providers natively (Anthropic, OpenAI, local), has a Companion App for macOS that gives you a menubar interface, and includes browser control, persistent memory, and dozens of community-built skills out of the box. The trade is operational complexity — ~434,000 lines of code, 70+ dependencies, single Node process with shared memory — and a security model that relies on application-level checks rather than OS isolation. Recent CVEs and security writeups in this space have mostly been openclaw-shaped.

    NanoClaw is the lighter, more opinionated alternative. ~3,900 lines of code, fewer than 10 dependencies, agents in isolated Linux containers with explicit mounts, single host process orchestrating per-session containers. Credential handling is delegated to OneCLI (NanoClaw’s companion credential proxy), which injects API keys at request time so agents never hold raw secrets — meaningful when an agent has bash access inside its container. The trade is that NanoClaw is built natively around the Claude Agent SDK — Claude Code is the primary harness, the slash commands that install channels and providers run inside Claude Code, and other providers (Codex, OpenCode, Ollama) are drop-in alternatives rather than peers. There’s no menubar app, no built-in dashboard, no UI beyond the chat channels you’ve installed. The codebase is small enough that “ask Claude Code to walk you through it” is a realistic onboarding strategy.

    For a personal-assistant use case, the openclaw trade-off probably wins. More features out of the box, more flexibility on providers, easier to bring up if you’re not already deep in the Claude Code ecosystem. For a pipeline-shaped workload — GTM, document processing, anything where the workflow exists independent of conversation — NanoClaw is structurally a better fit, and Claude Code being the assumed harness is actually an advantage rather than a constraint, because Claude Code is arguably the most capable AI authoring tool available right now and the framework is built around it.

    I went through both before settling. Here’s the rest of the comparison through the pipeline-shape lens.

    The shape of the workload matters

    A personal assistant is reactive. You send it something. It figures out what you meant, picks a tool, runs the tool, replies. The workflow is whatever the conversation is.

    A pipeline is the opposite. There’s a state machine. There are stages. Each prospect, ticket, document, or whatever the unit is moves through stages on its own clock. Some get stuck. Some get rerouted. Some need to be remembered six months later when a specific signal lights up. The workflow exists independent of any conversation.

    These two workloads want different things from a framework. The assistant wants flexibility, channels, plug-and-play tools, an LLM that figures out what to do. The pipeline wants determinism between stages, deterministic routing, dry-run capability, an LLM that does bounded judgment work inside a stage.

    This is the lens that matters. Most framework comparisons are feature bake-offs. The actual question is which workload shape you’re building.

    Three things that didn’t survive OpenClaw for me

    Routing. Openclaw’s agent picks what to do based on the inbound and its own reasoning. That’s the right model for “summarise my inbox” and the wrong model for “transition prospect ABC from awaiting-reply to unresponsive after 14 days.” The second decision has to be deterministic, replayable, dry-runnable, and outside the LLM. Tool-call routing is fine when the cost of a wrong decision is small. In a GTM pipeline a wrong routing decision is a duplicate touch, a wrong segment, a compliance breach.

    You can wire OpenClaw to do deterministic routing — through skill conditions, scheduled triggers, scripted control flow — but you’re working against the framework’s grain. Every hour spent there is an hour reinventing what a state machine engine gives you for free.

    Per-skill model preference. Pipelines benefit from heterogeneity. Small fast models for bulk discovery and augmentation. Larger models for content polish. Different providers for redundancy. OpenClaw supports multiple LLM backends as a first-class feature — you can configure Anthropic, OpenAI, or local models — but the routing decisions are made within the agent’s own reasoning rather than at the framework level. For a pipeline you want the framework to route deterministically based on skill family, not let the agent pick its own provider per call.

    NanoClaw’s approach is the opposite: provider is configured per agent group, one provider per group, multiple groups in parallel. That maps directly to “discovery and augmentation in one group on Nemotron, polish in another group on Claude.” Per-task provider hints would be cleaner, but group-level routing is what works today, and for most pipelines it’s enough because the natural skill boundaries align with provider preferences anyway.

    Operating cost. OpenClaw runs a websocket gateway with constant background activity. mDNS service discovery, periodic health probes, channel reconnect loops. On a 1GB droplet it spent most of its capacity on its own metabolism. Bumping the VPS works, but the symptom is telling.

    NanoClaw is much quieter at idle. The host process owns message queues, agent containers spin up per task, channels are explicit and minimal. A 2GB droplet has plenty of headroom for a working pipeline plus orchestrator plus operator UI.

    What NanoClaw doesn’t do, and why that’s useful

    NanoClaw has no built-in orchestrator. No state machine engine. No artifact store. No journal writer. No skill dispatcher. No dry-run harness. No business logic of any kind.

    For an assistant, this is missing functionality. For a pipeline, it’s the right scope.

    The orchestrator is the part that’s specific to your workflow. State transitions, when to retry, when to dead-letter, what counts as completion, what triggers the next stage. Building it as plain code (in any language; mine is TypeScript) means it stays readable, testable, and replaceable. NanoClaw runs the channel adapters and the agent containers. The orchestrator runs the workflow. They talk through structured task contracts.

    The trade is real: you write more code to start. The benefit is real: you understand and own every line of the pipeline that matters.

    What both share

    The skills system. Both frameworks treat skills as SKILL.md markdown files that the agent reads and executes. The same skills can technically run on either framework with minor adjustments, though the agent configuration files differ — openclaw uses SOUL.md for agent personality and config, NanoClaw uses CLAUDE.md for the same purpose. So you’re not locked into a framework by your skills library — you’re picking the framework that runs them at the right architectural layer.

    Both also lean on Claude Code as a useful authoring layer, though the relationship is different. NanoClaw is explicit about it — the slash commands that install channels and providers run inside Claude Code and copy source files into your fork from long-lived branches. OpenClaw is more flexible: you can author with Claude Code, edit config files by hand, or use whatever AI coding tool you prefer including the built in agents. Either way, having Claude Code in the loop is the best authoring experience available right now for both — it’s just that NanoClaw treats it as the assumption while openclaw treats it as one option among several.

    The forking model

    NanoClaw’s other design choice worth flagging: it’s opinionated about you forking the repo and treating the fork as your install. There’s no config-as-data layer that abstracts away your customizations. If you want different behaviour, you change the code. The codebase is small enough that this is safe.

    This is a discipline. It means every customization is a code change you can read and revert. It also means setup feels heavier than openclaw’s onboarding. For a pipeline you’ll be running for months, that’s the right trade. For a weekend assistant project, it’s overkill.

    The decision criteria, condensed

    Pick OpenClaw if:

    • You want a personal assistant that responds to messages on channels
    • The workflow is whatever the conversation is
    • You want maximum provider flexibility (Anthropic, OpenAI, local models all first-class)
    • You want a menubar app and guided onboarding out of the box
    • You’re fine with the larger codebase and application-level security model

    Pick NanoClaw if:

    • You’re building something with a state machine — pipeline-shaped, not chat-shaped
    • The workflow exists independent of any conversation
    • You need deterministic routing, dry-runs, replay
    • You want different providers for different stages, configured per agent group
    • You’re deep enough in Claude Code to leverage it as the authoring layer
    • You want OS-level container isolation as your security model
    • You’re willing to write the orchestrator yourself (and would rather, because you want to own the workflow logic)

    Worth knowing

    NanoClaw is younger and more spartan around setup edges — both because it does less by design and because the project is moving fast. If you hit a setup gotcha, the answer is usually in the docs and a quick edit by Claude Code resolves it. Filing an issue and waiting is the slower path. The flip side: the codebase is small enough that you can read all of it, and Claude Code can confidently make changes across it.

    OpenClaw has the larger community, more channel adapters in stable shape, and a richer ecosystem of community skills (ClawHub, the openclaw skills marketplace, has hundreds). If you’re operating in personal-assistant territory, those network effects matter. For pipelines, they don’t.

    Worth flagging for context: OpenClaw’s creator, Peter Steinberger, joined OpenAI in February 2026, with the project continuing as open source. The project’s velocity has been impressive but the security model has also been the subject of multiple writeups — anyone evaluating it for production should read the security analyses alongside the marketing copy.

    The full GTM system this comparison feeds into is in Building a GTM dark factory with Nemotron 3 and NanoClaw. For setup specifics — what it takes to actually run NanoClaw end to end — see the companion piece.

  • Installing n8n on Raspberry Pi 3B

    Installing n8n on Raspberry Pi 3B

    I recently decided to set up n8n on my Raspberry Pi 3B to automate my social media workflow, thanks to n8n’s availability for self hosted setups.

    The Pi was already running Pi-hole 24/7 as my network’s DNS server, so I wanted a solution that wouldn’t interfere with it. Here’s what I learned after trying the standard approach and eventually succeeding with Docker.

    The Failed Attempt: Direct Install

    I started with a guide designed for newer Raspberry Pis (Pi 4/5), following instructions from various tutorials that suggested a direct npm installation. The process seemed straightforward:

    bash

    # The approach that DIDN'T work on Pi 3B
    npm install n8n -g
    n8n start
    

    What went wrong: The installation would start, but then freeze the entire Pi. The limited 1GB RAM on the Pi 3B couldn’t handle the build process. I had to force restart the Pi multiple times. Even the uninstall and update commands wouldn’t work properly, leaving me to manually remove the n8n folder.

    The Solution: Docker Installation

    After the npm failures, I switched to Docker following instructions provided by Claude. This approach uses pre-built images, completely bypassing the resource-intensive build process. Here’s the complete setup that worked perfectly.

    Step 1: Install Docker

    bash

    # Install Docker
    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    
    # Add your user to docker group (avoids needing sudo)
    sudo usermod -aG docker $USER
    
    # Log out and back in for group changes to take effect
    

    Verify Docker is installed:

    bash

    docker --version
    

    Step 2: Install Docker Compose

    bash

    sudo apt-get update
    sudo apt-get install -y docker-compose
    

    Step 3: Create n8n Directory and Configuration

    bash

    # Create directory for n8n
    mkdir -p ~/n8n
    cd ~/n8n
    
    # Create docker-compose.yml
    cat > docker-compose.yml << 'EOF'
    version: '3.3'
    
    services:
      n8n:
        image: n8nio/n8n:latest
        container_name: n8n
        restart: unless-stopped
        ports:
          - "5678:5678"
        environment:
          - N8N_SECURE_COOKIE=false
        volumes:
          - ./data:/home/node/.n8n
    EOF
    

    Note on version: I initially used version: '3.8' but got an error about unsupported version. The older docker-compose on Pi 3B required version: '3.3'.

    Step 4: Fix Permissions (Critical!)

    bash

    # Create data directory and set proper permissions
    mkdir -p ~/n8n/data
    sudo chown -R 1000:1000 ./data
    

    This step is crucial. n8n runs as user ID 1000 inside the container and needs write access to save workflows, credentials, and configuration files.

    Step 5: Start n8n

    bash

    docker-compose up -d
    

    Check if it’s running:

    bash

    docker-compose ps
    docker-compose logs -f n8n
    

    The startup takes 30-60 seconds on a Pi 3B. Once you see logs indicating n8n is running, you can access it at http://[your-pi-ip]:5678 from any device on your network.

    Press Ctrl+C to exit the logs view (this doesn’t stop n8n, just stops viewing the logs).

    Key Configuration Choices

    Why N8N_SECURE_COOKIE=false?

    By default, n8n requires HTTPS for secure cookies. Since we’re running locally without SSL, this setting allows access from other devices on your network. This is perfectly safe for a home network setup.

    Why restart: unless-stopped?

    This ensures n8n automatically starts when your Pi reboots. Docker is configured to start on boot by default, and it will automatically restart any containers marked with this policy.

    Coexisting with Pi-hole

    The beauty of this setup is that n8n and Pi-hole run completely independently:

    • Pi-hole typically runs on port 53 (DNS) and 80/443 (web interface)
    • n8n runs on port 5678
    • Both use Docker’s default network, with no conflicts
    • Combined RAM usage is manageable on the Pi 3B

    Managing n8n

    Here are the essential commands (run from ~/n8n directory):

    bash

    # Stop n8n
    docker-compose stop
    
    # Start n8n
    docker-compose start
    
    # Restart n8n (useful after config changes)
    docker-compose restart
    
    # View logs
    docker-compose logs -f n8n
    
    # Update n8n to latest version
    docker-compose pull
    docker-compose up -d
    
    # Complete removal
    docker-compose down
    rm -rf ~/n8n
    

    Handling OAuth Credentials

    One challenge I encountered was setting up OAuth credentials (Google, LinkedIn, etc.) when accessing the local n8n from my MacBook. Many OAuth providers require the redirect URL to be either HTTPS or localhost.

    Solution: SSH Tunnel

    bash

    # On your Mac/laptop, create an SSH tunnel
    ssh -L 5678:localhost:5678 pi@[your-pi-ip]
    
    # Then access n8n at http://localhost:5678 in your browser
    

    This makes your browser think n8n is running locally, which satisfies OAuth requirements. Once credentials are saved, you can close the tunnel and access n8n normally via the Pi’s IP address. You only need the tunnel when initially setting up OAuth credentials.

    Performance Notes

    The Pi 3B handles n8n surprisingly well for automation workflows:

    • Startup time: 30-60 seconds after reboot
    • Workflow execution: Perfectly adequate for scheduled tasks
    • Web interface: Responsive enough for editing workflows
    • RAM usage: n8n + Pi-hole combined use ~45%, leaving headroom

    For workflows that need AI processing (like my LinkedIn post generator), I’m calling LM Studio running on my MacBook over the network. The Pi handles the orchestration, while the heavy AI work happens on more powerful hardware.

    Troubleshooting Tips

    If the container keeps restarting: Check permissions on the data folder. The error logs will show “EACCES: permission denied” if this is the issue.

    If you can’t access from other devices: Make sure you’ve set N8N_SECURE_COOKIE=false in the environment variables and restarted the container.

    If Docker isn’t starting on boot: Enable it with sudo systemctl enable docker

    Final Thoughts

    The Docker approach transformed what seemed like an impossible task into a straightforward 10-minute setup. While the Pi 3B isn’t powerful enough to compile n8n from source, it’s more than capable of running the pre-built Docker image alongside Pi-hole.

    If you’re running a Pi 3B and want to add n8n to your home automation stack, skip the npm route entirely and go straight to Docker. Your Pi (and your sanity) will thank you.

    Complete Setup Script

    For reference, here’s the entire setup in one script:

    bash

    #!/bin/bash
    
    # Install Docker
    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    sudo usermod -aG docker $USER
    
    # Install Docker Compose
    sudo apt-get update
    sudo apt-get install -y docker-compose
    
    # Create n8n directory
    mkdir -p ~/n8n
    cd ~/n8n
    
    # Create docker-compose.yml
    cat > docker-compose.yml << 'EOF'
    version: '3.3'
    
    services:
      n8n:
        image: n8nio/n8n:latest
        container_name: n8n
        restart: unless-stopped
        ports:
          - "5678:5678"
        environment:
          - N8N_SECURE_COOKIE=false
        volumes:
          - ./data:/home/node/.n8n
    EOF
    
    # Create and set permissions on data directory
    mkdir -p data
    sudo chown -R 1000:1000 ./data
    
    # Start n8n
    docker-compose up -d
    
    echo "n8n is starting up. Access it at http://$(hostname -I | awk '{print $1}'):5678 in about 60 seconds."
    echo "View logs with: docker-compose logs -f n8n"
    

    Save this as install-n8n.sh, make it executable with chmod +x install-n8n.sh, and run it with ./install-n8n.sh. Note that you’ll need to log out and back in after the script runs for Docker group permissions to take effect, then run docker-compose up -d from the ~/n8n directory.

  • GitHub’s SpecKit: The Structure Vibe Coding Was Missing

    GitHub’s SpecKit: The Structure Vibe Coding Was Missing

    When I first started experimenting with “vibe coding,” building apps with AI agents felt like a superpower. The ability to spin up prototypes in hours was exhilarating. But as I soon discovered, the initial thrill came with an illusion. It was like managing a team of developers with an attrition rate measured in minutes—every new prompt felt like onboarding a fresh hire with no idea what the last one had been working on.

    The productivity boost was real, but the progress was fragile. The core problem was context—a classic case of the law of leaky abstractions applied to AI. Models would forget why they made certain choices or break something they had just built. To cope, I invented makeshift practices: keeping detailed dev context files, enforcing strict version control with frequent commits, and even asking the model to generate “reset prompts” to re-establish continuity. Messy, ad hoc, but necessary.

    That’s why GitHub’s announcement of SpecKit immediately caught my attention. SpecKit is an open-source toolkit for what they call “spec-driven development.” Instead of treating prompts and chat logs as disposable artifacts, it elevates specifications to first-class citizens of the development lifecycle.

    In practice, this means:

    • Specs as Durable Artifacts: Specifications live in Git alongside your code—permanent, version-controlled, and not just throwaway notes.
    • Capturing Intent: They document the why—the constraints, purpose, and expected behavior—so both humans and AI stay aligned.
    • Ensuring Continuity: They serve as the source of truth, keeping projects coherent across sessions and contributors.

    For anyone who has tried scaling vibe coding beyond a demo, this feels like the missing bridge. It brings just enough structure to carry a proof-of-concept into maintainable software.

    And it fits into a larger story. Software engineering has always evolved in waves—structured programming, agile, test-driven development. Each wave added discipline to creativity, redefining roles to reflect new economic realities—a pattern we’re seeing again with agentic coding. Spec-driven development could be the next step:

    • Redefining the Developer’s Role: Less about writing boilerplate, more about designing robust specs that guide AI agents.
    • Harnessing Improvisation: Keeping the creative energy of vibe coding, but channeling it within a coherent framework.
    • Flexible Guardrails: Not rigid top-down rules, but guardrails that allow both creativity and scalability.

    Looking back, my dev context files and commit hygiene were crude precursors to this very idea. GitHub’s SpecKit makes clear that those instincts weren’t just survival hacks—they pointed to where the field is heading.

    The real question now isn’t whether AI can write code—we know it can. The question is: how do we design the frameworks that let humans and AI build together, reliably and at scale?

    Because as powerful as vibe coding feels, it’s only when we bring structure to the improvisation that the music really starts.


    👉 What do you think—will specs become the new lingua franca between humans and AI?

  • Dubai Diaries: Running LLMs & Stable Diffusion locally on a gaming laptop

    Dubai Diaries: Running LLMs & Stable Diffusion locally on a gaming laptop

    I previously wrote about the second device that I got about coming to Dubai, but not much about the first one which was a gaming laptop. So here’s a bit about the laptop which also doubles as a local AI driver thanks to the Nvidia GPU (the RTX3060).

    Soon after getting it back in 2022, I tried running the Stable Diffusion models and it was quite a bit of an upgrade over my original attempt on a plain GPU-less Windows machine. The generation times came down to 10s or so, and has gotten even faster as the models and tools have been optimised over the last couple of years. There are quite a few projects available on GitHub if you want give it a try – AUTOMATIC1111 and easydiffusion are among the more popular options. Nvidia has also got a TensorRT extension to further improve performance.

    With that out of the way, I also discovered LM Studio which allows you to run LLMs locally with a chat like interface thrown in, and you can access a bunch of models like Meta’s LLama. The response times are of course not as fast as the freely available online options like ChatGPT, Claude, Gemini and the likes, but you effectively get unlimited access to the model.

    Here’s an example from a conversation I had with LLama regarding the coffee meme from Ace Attorney game series:

  • Wenger 16999 Swiss Army Knife Giant

    Giant all right, and weighs just 7.2 pounds. The Wenger Giant Knife includes 87 implements for almost any situation:

    • 2.5-inch 60% serrated locking blade
    • Nail file
    • Nail cleaner
    • Corkscrew
    • Adjustable pliers with wire crimper and cutter
    • Removable screwdriver bit adapter
    • 2.5-inch blade for Official World Scout Knife
    • Spring-loaded, locking needle-nose pliers with wire cutter
    • Removable screwdiver bit holder
    • Phillips head screwdriver bit 0 Phillips head screwdriver bit 1
    • Phillips head screwdriver bit 2
    • Flat head screwdriver bit 0.5mm x 3.5mm
    • Flat head screwdriver bit 0.6mm x 4.0mm
    • Flat head screwdriver bit 1.0mm x 6.5mm
    • Magnetized recessed bit holder
    • Double-cut wood saw with ruler
    • Chain rivet setter
    • Removable 5mm
    • Allen wrench
    • Screwdriver for slotted and Phillips head screws
    • Removable tool for adjusting spokes
    • 10mm Hexagonal key for nuts
    • Removable 4mm curved allen wrench with Phillips head screwdriver
    • Patented locking screwdriver
    • Universal wrench
    • 2.4-inch springless scissors with serrated self-sharpening design
    • 1.65-inch clip point utility blade
    • Phillips head screwdriver
    • 2.5-inch clip-point blade
    • Club face cleaner
    • 2.4-inch round tip blade
    • Patented locking screwdriver
    • Cap lifter
    • Can opener
    • Shoe spike wrench
    • Divot repair tool
    • 4mm Allen wrench
    • 2.5-inch blade
    • Fine metal file with precision screwdriver
    • Double-cut wood saw with ruler
    • Cupped cigar cutter with double honed edges
    • 12/20-gauge choke tube tool
    • Watch case back opening tool
    • Snap shackle
    • Mineral crystal magnifier
    • Compass
    • Straight edge, ruler (in./cm)
    • Telescopic pointer
    • Fish scaler
    • Hook dis-gorger
    • Line guide
    • Shortix laboratory key
    • Micro tool holder
    • Micro tool adapter
    • Micro scraper, straight
    • Micro scraper,curved
    • Laser pointer with 300-foot range
    • Metal file
    • Metal saw
    • Flashlight
    • Micro tool holder
    • Phillips head screwdriver 1.5mm
    • Screwdriver 1.2mm
    • Screwdriver .8mm
    • Fine fork for watch spring bars
    • Reamer
    • Pin punch 1.2mm
    • Pin pinch .8mm
    • Round needle file
    • Removable tool holder with expandable receptacle
    • Removable tool holder
    • Special self-centering screwdriver for gunsights
    • Flat Phillips head screwdriver
    • Chisel-point reamer
    • Mineral crystal magnifier
    • Small ruler
    • Extension tool
    • Sping-loaded, locking flat nose needle-nose pliers
    • Removable screwdriver bit holder
    • Phillips head screwdriver bit 0
    • Phillips head screwdriver bit 1
    • Phillips head screwdriver bit 2
    • Flat head screwdriver bit 0.5mm x 3.5mm
    • Flat head screwdriver bit 0.6mm x 4.0mm
    • Flat head screwdriver bit 1.0mm x 6.5mm
    • Magnetized recessed bit holder
    • Tire tread gauge
    • Fiber optic tool holder
    • Can opener
    • Patented locking screwdriver
    • Cap lifter
    • Wire stripper
    • Reamer
    • Awl
    • Toothpick
    • Tweezers
    • Key ring

    Wenger 16999 Swiss Army Knife Giant – Amazon.com.