{"id":19253423,"url":"https://github.com/stevearc/pair-ls","last_synced_at":"2025-04-21T14:32:05.617Z","repository":{"id":139186909,"uuid":"455431190","full_name":"stevearc/pair-ls","owner":"stevearc","description":"Editor-agnostic remote pair programming","archived":false,"fork":false,"pushed_at":"2022-12-12T20:45:03.000Z","size":146,"stargazers_count":29,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T21:08:24.561Z","etag":null,"topics":["pair-programming","pairing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stevearc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-04T05:21:12.000Z","updated_at":"2025-01-28T08:39:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"d858537b-6aac-40f9-9f7f-874480e6fc1e","html_url":"https://github.com/stevearc/pair-ls","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stevearc%2Fpair-ls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stevearc%2Fpair-ls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stevearc%2Fpair-ls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stevearc%2Fpair-ls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stevearc","download_url":"https://codeload.github.com/stevearc/pair-ls/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250070265,"owners_count":21369845,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pair-programming","pairing"],"created_at":"2024-11-09T18:30:50.760Z","updated_at":"2025-04-21T14:32:05.606Z","avatar_url":"https://github.com/stevearc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pair-ls\n\nPair-ls is a lightweight, editor-agnostic tool for remote pair-programming. It\nallows you to easily share the files you are working on in a read-only manner.\nPair-ls is _not_ a collaborative editor. If you're wondering why you would use\npair-ls, read the [comparison](#comparison) section.\n\n- [Installation](#installation)\n- [Setup](#setup)\n- [Sharing](#sharing)\n- [Configuration](#configuration)\n- [Comparison](#comparison)\n- [Alternatives](#alternatives)\n- [Technical Overview](#technical-overview)\n\nhttps://user-images.githubusercontent.com/506791/155237457-8478eb05-8bcc-4a0f-ba76-0a07a206edda.mp4\n\n## Installation\n\nYou can download a binary from [the releases\npage](https://github.com/stevearc/pair-ls/releases)\n\nIf you want to build from source, `git clone` this repo and run `yarn build`\n(you will need to [install\nyarn](https://classic.yarnpkg.com/lang/en/docs/install/) and [go build tools](https://go.dev/doc/install))\n\n## Setup\n\nIf the option is available, it is recommended to use a plugin for your editor.\nIf your editor is not yet supported, you can still use pair-ls with minimal\nconfiguration (also file an issue to ask for support). Using pair-ls without an\neditor plugin will mean some degradation in the cursor tracking.\n\n**Editor plugins:**\n\nSee the link for installation instructions\n\n- Neovim: [pair-ls.nvim](https://github.com/stevearc/pair-ls.nvim)\n- VS Code: [pair-ls-vscode](https://github.com/stevearc/pair-ls-vscode)\n\n### Generic Setup - any editor\n\npair-ls supports any editor with a [LSP\nclient](https://microsoft.github.io/language-server-protocol/).\n\nConfigure your LSP client to run this command as a server: `pair-ls lsp -port 8080`.\nNow you can visit http://localhost:8080 to see a mirror of your code. For more\ninfo on how to share this page, see [Sharing](#sharing).\n\n## Sharing\n\nRunning `pair-ls lsp -port 8080` is an easy way to get started, but how can you\nshare this across the internet?\n\nThe quickest way with no setup required is to use [WebRTC\nconnections](docs/WEBRTC.md).\n\nYou can use [ngrok](https://ngrok.com/) or a server you control to [forward your\nweb port](docs/PORT_FORWARDING.md).\n\nIf you'd prefer the server act as a full intermediary, you can set up [a relay\nserver](docs/RELAY.md).\n\nFor completeness, you can also set up a [signal server](docs/SIGNAL.md), but\nthat has all the drawbacks of both WebRTC and relay server, so it's not\nrecommended.\n\n### Password protection\n\nIf your pair-ls webpage is visible on the public internet, you should make sure\nto enable password protection to prevent anyone on the internet from seeing your\ncode. Simply provide a password, either via the [config file](#configuration) or\nwith the environment variable `PAIR_WEB_PASS`. The webserver will now require\nthis password before allowing access. You should also make sure your site it\nhosted over https so the password can't be trivially sniffed (see\n[encryption](docs/RELAY.md#encryption)).\n\n## Configuration\n\nThe configuration file can be found at `$XDG_CONFIG_HOME/pair-ls.toml`. Most\nvalues can be specified on the command line instead, if you prefer (run\n`pair-ls` for detailed help).\n\n```toml\n# Default log file is $XDG_CACHE_HOME/pair-ls.log\nlogFile = \"/path/to/file.log\"\n\n# For the relay server. When false (the default) all files are cleared from the\n# server when the last editor connection is closed.\nrelayPersist = false\n\n# The static site hosting the WebRTC connection code\nstaticRTCSite = \"https://code.stevearc.com/\"\n\n# The one-time WebRTC connection token generated from the static WebRTC site\n# Editor plugins provide a better way to pass this in, so only use the option if\n# your editor doesn't have a plugin.\ncallToken = \"\"\n\n[server]\n# If provided, will require password auth from web client\nwebPassword = \"passw0rd\"\n# If provided, will require connecting pair-ls LSP to provide this password in\n# the [client] section (only used for relay \u0026 signal servers)\nlspPassword = \"secur3\"\n# If provided, will secure all connections with TLS\ncertFile = \"/path/to/cert.pem\"\n# If the private key is not in the certFile PEM, you can pass it in separately here\nkeyFile = \"/path/to/cert.key.pem\"\n# If true, will require pair-ls LSP to provide a matching client cert.\n# This is the certFile under the [client] section.\nrequireClientCert = false\n# PEM file with one or more certs that pair-ls LSP can match\n# (when requireClientCert = true; only used for relay \u0026 signal servers)\nclientCAs = \"/path/to/pool.pem\"\n\n[client]\n# Provide this certificate to the relay/signal server when connecting\ncertFile = \"/path/to/cert.pem\"\n# If the private key is not in the certFile PEM, you can pass it in separately here\nkeyFile = \"/path/to/cert.key.pem\"\n# If the relay/signal server requires a password, supply it here\npassword = \"secur3\"\n```\n\n## Comparison\n\nPairing tools fall into roughly 3 categories: **screen sharing**, **web\neditors**, and **editor plugins**.\n\n**Screen sharing**: Easiest to use, with the worst functionality\n\n- **Pros**:\n  - Very easy, they're built into the tools you're already using to call your partners\n  - You see exactly what the sharer is doing, across all windows and applications\n- **Cons**:\n  - Video artifacts can make text hard to read\n  - Text is often too small unless the sharer increases the size dramatically\n  - Viewer has no control over what they're looking at\n  - Read-only sharing\n\n**Web editor**: Easy to share, but only if you buy into their ecosystem\n\n- **Pros**:\n  - No installation required\n  - Often have collaborative editing functionality\n- **Cons**:\n  - You have to use their editor\n  - You have to use their entire editing ecosystem, since it's not simply working with files on your own computer\n\n**Editor plugin**: Best experience as long as everyone's preferred editor is supported\n\n- **Pros**:\n  - You can use your own editor\n  - Often have collaborative editing functionality\n- **Cons**:\n  - Requires installation\n  - Your editor has to have a plugin available\n  - Everyone has to be using the same editor\n  - Only shares editor state, nothing in other windows\n\n**Pair-ls**: Sacrifices features of editor plugins for broader support\n\n- **Pros**:\n  - You can use your own editor\n- **Cons**:\n  - Requires installation\n  - Read-only sharing\n  - Only shares files. You can't see open terminals or anything else the sharer is doing in the editor\n\n## Alternatives\n\nMost of these are paid apps/services, though many of those have a free tier.\n\n- Screen sharing\n  - [Tuple](https://tuple.app/) (paid)\n  - [Pop](https://pop.com/) (paid)\n  - [Coscreen](https://www.coscreen.co/) (paid)\n  - [Drovio](https://www.drovio.com/) (paid)\n  - Plus all of the generic services like Zoom, Google Meet, Facebook Messenger,\n    etc.\n- Web editor\n  - [Replit](https://replit.com/) (paid)\n  - [Codeanywhere](https://codeanywhere.com/) (paid)\n  - [CodeSandbox](https://codesandbox.io/) (paid)\n  - [Cloud9](https://aws.amazon.com/cloud9/) (only AWS usage fees)\n  - [Red Hat\n    CodeReady](https://developers.redhat.com/products/codeready-workspaces/overview)\n- Editor plugin\n  - [Microsoft Live\n    Share](https://visualstudio.microsoft.com/services/live-share/)\n    (VSCode, Visual Studio)\n  - [Floobits](https://floobits.com/) (IntelliJ, Sublime, Atom, Neovim, Emacs) (paid)\n  - [Duckly](https://duckly.com/) (VSCode, IntelliJ) (paid)\n  - [CodeTogether](https://www.codetogether.com/) (VSCode, IntelliJ, Eclipse)\n    (paid)\n  - [Teletype](https://teletype.atom.io/) (Atom)\n  - [instant.nvim](https://github.com/jbyuki/instant.nvim) (Neovim)\n  - [crdt.el](https://code.librehq.com/qhong/crdt.el) (Emacs)\n\n## Technical Overview\n\npair-ls is implemented as a [Language\nServer](https://microsoft.github.io/language-server-protocol/), so it receives\nfile open and edit information from any LSP client. It is a simple matter to\nthen expose that information to a web client, or to replicate it to a relay server.\n\nEditor plugins add extensions on top of LSP to allow for enhanced features (see\ndifferences in [Setup](#setup)) that aren't possible with the current state of\nLSP (e.g. tracking cursor movement).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevearc%2Fpair-ls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstevearc%2Fpair-ls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevearc%2Fpair-ls/lists"}