Linux system-wide install over an existing Lua GitHub issue

vibecode
{"vibecode": {
    "doc": "linux_system_wide_install_with_existing_lua",
    "role": "narrative walkthrough — Linux user picks system-wide install on a machine that already has Lua installed; covers detection, coexistence, and final file layout showing both the pre-existing Lua and Caspian's bundled Lua side by side",
    "audience": "Linux user with sudo, already has Lua N.M installed at /usr/local/bin/lua",
    "key_design_point": "Caspian always uses its own bundled Lua; never shares or upgrades the system's Lua",
    "status": "brainstorm — describes what V1.0 install should feel like"
}}

The user already has Lua installed on their machine — maybe it came with the OS, maybe they installed it for a different project, maybe it's a totally different version (5.1, 5.3, anything). They want to install Caspian system-wide.

This story shows what happens. Short version: Caspian always bundles and uses its own Lua. The existing Lua on the system is left completely alone.

For the standard interactive flow, see linux.md. This story is just the variant where existing-Lua-detection comes up.


Starting state GitHub issue

bash
$ which lua
/usr/local/bin/lua
$ lua -v
Lua 5.3.6  Copyright (C) 1994-2020 Lua.org, PUC-Rio

Lua 5.3 is already on PATH. Caspian needs Lua 5.4, so this isn't a version we can share even if we wanted to.


Run the installer GitHub issue

bash
$ curl -fsSL https://puck.uno/install | sh

Same one-liner as the standard flow. Behind the scenes, the wrapper script probes for an existing lua on PATH as part of its pre-flight checks.


The conversation GitHub issue

Welcome to Caspian.

I'll install Caspian on this machine. A few questions — press
enter to accept any default.

Note: I found Lua 5.3 at /usr/local/bin/lua already on this machine.
That's fine — Caspian bundles its own Lua 5.4 and won't touch your
existing one. They'll coexist side by side.

Install for:  [u] just you,  [s] system-wide  [u]: s

System-wide install requires root. I'll re-run with sudo.

[sudo] password for user: ********

Install location  [/usr/local]:

Shell rc update: not needed (/usr/local/bin is already on PATH).

Ready to install:
   Caspian:    /usr/local  (system-wide; available to all users)
   Examples:   /usr/local/lib/caspian/examples  (bundled, read-only)

   Your existing Lua at /usr/local/bin/lua stays where it is —
   Caspian's bundled Lua 5.4 goes under /usr/local/lib/caspian/lua/
   and is only invoked by the caspian launcher.

Proceed?  [Y/n]:

Installing...
   ✓ Launcher placed at /usr/local/bin/caspian
   ✓ Engine, stdlib, and libraries placed under /usr/local/lib/caspian
   ✓ Bundled Lua 5.4 placed under /usr/local/lib/caspian/lua
   ✓ Bundled examples placed under /usr/local/lib/caspian/examples

Done. Try this in any shell, as any user on this machine:

   echo "puts 'hello, world'" > hello.casp
   caspian hello.casp

The existing 'lua' command still works as it did before:

   $ lua -v
   Lua 5.3.6 …

Welcome aboard.

Why Caspian bundles its own Lua GitHub issue

Three reasons, none of them about distrust:


Where files end up GitHub issue

After install, both Luas live on the system side by side:

/usr/local/
├─ bin/
│  ├─ lua                    # the user's existing Lua 5.3 (untouched)
│  ├─ luac                   # the user's existing Lua 5.3 compiler (untouched)
│  └─ caspian                # NEW — Caspian launcher
└─ lib/
   ├─ liblua.so.5.3          # the user's existing Lua 5.3 shared lib (untouched)
   └─ caspian/               # NEW — everything Caspian needs
      ├─ lua/                # bundled Lua 5.4 (separate from the system's)
      │  ├─ bin/lua          # invoked only by the caspian launcher
      │  └─ lib/liblua.so.5.4
      ├─ lib/
      │  ├─ libsodium.so     # signing + random bytes (minimal build)
      │  └─ lua/5.4/
      │     ├─ lpeg.so       # rpath-resolved
      │     └─ luasodium.so  # rpath-resolved
      ├─ caspian/            # engine + stdlib (pure Lua)
      ├─ examples/           # bundled examples (read-only)
      └─ install.casp        # the installer itself, preserved

What if the existing Lua was version 5.4? GitHub issue

Same outcome. Caspian still uses its own bundled copy. The reason isn't "Caspian doesn't trust the system Lua" — it's that the C extensions Caspian bundles (LPeg, luasodium) are compiled against the exact bytes of the bundled Lua. Using a different binary, even the same version, can subtly mismatch the ABI in ways that break at runtime, not at link time.

Treating the bundle as a closed unit means every install behaves identically regardless of host. That predictability is worth ~250 KB of disk.


Uninstall GitHub issue

The user's pre-existing Lua is independent of Caspian, so uninstalling Caspian doesn't touch it:

bash
$ sudo rm -rf /usr/local/lib/caspian /usr/local/bin/caspian

After this, which lua still returns /usr/local/bin/lua (the user's), and which caspian returns nothing — clean removal.


Open questions GitHub issue

vibecode
{"vibecode": {"open_questions":
["whether_to_announce_existing_lua_detection_in_the_default_install_or_only_when_versions_differ",
"how_to_handle_existing_caspian_install_at_the_target_prefix",
"whether_to_warn_if_user_has_a_lua_5_4_install_pointing_out_the_bundle_is_used_anyway"]}}

© 2026 Puck.uno