Build GitHub Copilot

KINDAreplaces $10/mosaves $120/yrback to the verdict

0%0 of 20 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A Tabby server on your own machine or a GPU box, serving fill-in-the-middle completions to VS Code and JetBrains through official plugins, indexing your repositories for context, with latency measured rather than assumed and an acceptance rate you can compare against the subscription you left.

estimated effort weekendthe files for this build are in the project pack

Completion serverTabby, self-hostedCompletion modelA code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardwareHardwareAn NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with MetalEditorsThe official Tabby plugins for VS Code and JetBrainsMeasurementA local log of latency and acceptance

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. have readyfree if you already have suitable hardware; a suitable GPU otherwise starts in the high hundreds of USD, which is the figure the comparison in Phase 5 has to justify

    Why This is the prerequisite that decides whether the project is viable. Below it, Tabby falls back to CPU and completions arrive too late to be useful.

    Get it Check an existing machine first with nvidia-smi. An RTX 20-series or newer qualifies. Apple silicon uses the Metal path instead and works well for smaller models.

    Verify nvidia-smi reports compute capability 7.0 or higher, or you are on Apple silicon

  2. installfree

    Why The container image is the fastest route to a running server, but it needs the GPU visible inside the container.

    Get it Install Docker, then the NVIDIA container toolkit on Linux. On Apple silicon, use the native build rather than a container. open ↗

    Verify docker run --gpus all reports the GPU, or the native binary starts and reports the Metal device

  3. installfree

    Why The plugin is what turns a completion endpoint into ghost text. Writing your own is a project of its own.

    Get it Install from your editor's plugin marketplace and point it at your server address.

    Verify The plugin's status indicator shows connected

  4. have readyfree, but it must be done first

    Why Phase 5 compares against them, and once you have cancelled the subscription you cannot go back and measure.

    Get it Spend a morning with the paid tool, logging how often you accept a completion and roughly how fast they arrive. Record it before you start.

    Verify A written baseline exists with an acceptance rate and a latency impression

  5. have readyfree

    Why Models and indexes are large, and a model download that fails halfway through a full disk wastes an evening.

    Get it Check free space before pulling a model. Larger models need considerably more.

    Verify df reports at least twenty gigabytes free

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- This is a deployment, so the model that matters is your operational state, not a schema.
- server · the Tabby instance, its bound address, its model and its device
- index · which repositories are indexed, when, and how large the index is
- completions(t, latency_ms, accepted, model, language, prefix_len) · your own log, because acceptance rate is the only honest quality measure
- baseline · the latency and acceptance figures from the subscription you are replacing, recorded before you cancel it

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
TABBY_HOSTrequired127.0.0.1Bind address. Keep it on loopback unless you have deliberately added authentication.
TABBY_PORTrequired8080The port the completion server listens on.
TABBY_MODELrequiredStarCoder2-3BThe completion model. Chosen by the measurement in Phase 2, not by parameter count.
TABBY_DEVICErequiredcudacuda, metal or cpu. The cpu value is a diagnostic, not a working configuration.
TABBY_TOKENsecretoptionalreplace-with-a-random-tokenProduct phase only. Required the moment the server listens on anything but loopback.
COMPLETION_LOG_PATHrequired~/.local/share/tabby/completions.sqliteYour own latency and acceptance log. This is what makes Phase 5 possible.

The build, in order

  1. Hardware truth and a first completion

    A completion appears in your editor, and you know whether your hardware can serve them fast enough to be useful.

    1. Check the GPU model and its compute capability, or confirm Apple silicon. Write the answer down before installing anything, because it constrains every later choice.

      terminal
      nvidia-smi --query-gpu=name,compute_cap --format=csv
    2. Start with the smallest completion model that fits comfortably. A model that barely fits will swap and be slower than a smaller one that does not.

      terminal
      docker run -it --gpus all -p 8080:8080 -v $HOME/.tabby:/data tabbyml/tabby serve --model StarCoder2-3B --device cuda
    3. Install the Tabby VS Code plugin, point it at your server, and record the time from keystroke to ghost text over twenty completions.

      Files notes/latency.md

    done when · tick each as it passes
    watch out
    • Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it.
  2. Choosing a model by measurement

    You picked the model on evidence rather than on parameter count.

    1. Record latency, language and whether you accepted it. The plugin can be configured to log, or you can wrap the server endpoint.

      Files scripts/log_completions.py

    2. A morning each, on code you were writing anyway. Synthetic prompts will mislead you because they lack the surrounding file.

    3. Model, latency, acceptance and the reason. In three months you will not remember why, and you will be tempted to re-test.

      Files docs/model-choice.md

    done when · tick each as it passes
    watch out
    • A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not.
  3. Repository context

    Completions know about the rest of your codebase, not just the open file.

    1. Add each repository to the server configuration with an exclusion list. Start from .gitignore and add credential paths.

      Files ~/.tabby/config.toml

    2. A periodic job. An index that reflects last month's code is worse than useless because it confidently suggests names you have since renamed.

    3. Define a distinctively named function in one file and start calling it in another. If the completion knows the signature, indexing is doing something.

    done when · tick each as it passes
    watch out
    • Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote.
  4. Availability and the offline case

    The server is there when you start work, and the editor is usable when it is not.

    1. A systemd unit, a launchd agent or a restart policy on the container. Confirm by rebooting rather than by reading the configuration.

      terminal
      systemctl --user enable --now tabby
    2. Stop the server and work for ten minutes. Anything worse than a missing suggestion is a bug worth fixing before you rely on this.

    3. Inspect the bound address. If it is not loopback, add a token and verify an unauthenticated request is refused.

      terminal
      ss -tlnp | grep 8080
    done when · tick each as it passes
    watch out
    • A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended.
  5. Was it worth it

    You can answer the question with numbers instead of a feeling.

    1. Accepted completions over offered completions, by language. Aggregate hides that it may be excellent for one language and useless for another.

      Files scripts/report.py

    2. Hardware amortised, electricity, and your setup time at whatever you value it. Compare with the annual subscription.

      Files docs/comparison.md

    3. Including the case where you go back. A documented negative result is worth more than a quiet retreat.

      Files docs/comparison.md

    done when · tick each as it passes
    watch out
    • Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more dev tools.