{"id":13394325,"url":"https://github.com/automerge/automerge","last_synced_at":"2025-05-12T05:32:44.058Z","repository":{"id":37048282,"uuid":"230250903","full_name":"automerge/automerge","owner":"automerge","description":"A JSON-like data structure (a CRDT) that can be modified concurrently by different users, and merged again automatically. ","archived":false,"fork":false,"pushed_at":"2025-05-09T17:00:20.000Z","size":67530,"stargazers_count":4737,"open_issues_count":108,"forks_count":190,"subscribers_count":37,"default_branch":"main","last_synced_at":"2025-05-12T02:46:11.387Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://automerge.org","language":"JavaScript","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/automerge.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,"zenodo":null}},"created_at":"2019-12-26T11:15:38.000Z","updated_at":"2025-05-11T21:15:17.000Z","dependencies_parsed_at":"2024-01-30T04:28:07.829Z","dependency_job_id":"be5a6cdd-2751-429d-accc-ff52635090a1","html_url":"https://github.com/automerge/automerge","commit_stats":{"total_commits":1162,"total_committers":46,"mean_commits":25.26086956521739,"dds":0.7185886402753873,"last_synced_commit":"ec3b085bb6d420dba5519d2cb01fad5f34afeeda"},"previous_names":["automerge/automerge-rs","alexjg/automerge-rs"],"tags_count":137,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automerge%2Fautomerge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automerge%2Fautomerge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automerge%2Fautomerge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automerge%2Fautomerge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/automerge","download_url":"https://codeload.github.com/automerge/automerge/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253672734,"owners_count":21945482,"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":[],"created_at":"2024-07-30T17:01:16.074Z","updated_at":"2025-05-12T05:32:44.010Z","avatar_url":"https://github.com/automerge.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Applications","Uncategorized","Collaboration Editing","Libraries","协议相关","others","Web Frontend","Implementations","Server","\u003ca name=\"JavaScript\"\u003e\u003c/a\u003eJavaScript"],"sub_categories":["Uncategorized","CRDT","JS Libraries \u0026 Utilities","Data Structures","JavaScript"],"readme":"# Automerge\n\n\u003cimg src='./img/sign.svg' width='500' alt='Automerge logo' /\u003e\n\n[![homepage](https://img.shields.io/badge/homepage-published-informational)](https://automerge.org/)\n[![main docs](https://img.shields.io/badge/docs-main-informational)](https://automerge.org/automerge/automerge/)\n[![latest docs](https://img.shields.io/badge/docs-latest-informational)](https://docs.rs/automerge/latest/automerge)\n[![ci](https://github.com/automerge/automerge/actions/workflows/ci.yaml/badge.svg)](https://github.com/automerge/automerge/actions/workflows/ci.yaml)\n[![docs](https://github.com/automerge/automerge/actions/workflows/docs.yaml/badge.svg)](https://github.com/automerge/automerge/actions/workflows/docs.yaml)\n\nAutomerge is a library which provides fast implementations of several different\nCRDTs, a compact compression format for these CRDTs, and a sync protocol for\nefficiently transmitting those changes over the network. The objective of the\nproject is to support [local-first](https://www.inkandswitch.com/local-first/) applications in the same way that relational\ndatabases support server applications - by providing mechanisms for persistence\nwhich allow application developers to avoid thinking about hard distributed\ncomputing problems. Automerge aims to be PostgreSQL for your local-first app.\n\nIf you're looking for documentation on the JavaScript implementation take a look\nat https://automerge.org/docs/hello/. There are other implementations in both\nRust and C, but they are earlier and don't have documentation yet. You can find\nthem in `rust/automerge` and `rust/automerge-c` if you are comfortable\nreading the code and tests to figure out how to use them.\n\nIf you're familiar with CRDTs and interested in the design of Automerge in\nparticular take a look at https://automerge.org/automerge-binary-format-spec.\n\nFinally, if you want to talk to us about this project please [join our Discord server](https://discord.gg/HrpnPAU5zx)!\n\n## Status\n\nThis project is formed of a core Rust implementation which is exposed via FFI in\njavascript+WASM, C, and soon other languages. Alex\n([@alexjg](https://github.com/alexjg/)) is working full time on maintaining\nautomerge, other members of Ink and Switch are also contributing time and there\nare several other maintainers. The focus is currently on shipping the new JS\npackage. We expect to be iterating the API and adding new features over the next\nsix months so there will likely be several major version bumps in all packages\nin that time.\n\nIn general we try and respect semver.\n\n### JavaScript\n\nA stable release of the javascript package is currently available as\n`@automerge/automerge@2.0.0` where. pre-release verisions of the `2.0.1` are\navailable as `2.0.1-alpha.n`. `2.0.1*` packages are also available for Deno at\nhttps://deno.land/x/automerge\n\n### Rust\n\nThe rust codebase is currently oriented around producing a performant backend\nfor the Javascript wrapper and as such the API for Rust code is low level and\nnot well documented. We will be returning to this over the next few months but\nfor now you will need to be comfortable reading the tests and asking questions\nto figure out how to use it. If you are looking to build rust applications which\nuse automerge you may want to look into\n[autosurgeon](https://github.com/automerge/autosurgeon)\n\n## Repository Organisation\n\n- `./rust` - the rust rust implementation and also the Rust components of\n  platform specific wrappers (e.g. `automerge-wasm` for the WASM API or\n  `automerge-c` for the C FFI bindings)\n- `./javascript` - The javascript library which uses `automerge-wasm`\n  internally but presents a more idiomatic javascript interface\n- `./scripts` - scripts which are useful to maintenance of the repository.\n  This includes the scripts which are run in CI.\n- `./img` - static assets for use in `.md` files\n\n## Building\n\nTo build this codebase you will need:\n\n- `rust`\n- `node`\n- `yarn`\n- `cmake`\n- `cmocka`\n- `doxygen`\n- `ninja`\n\nYou will also need to install the following with `cargo install`\n\n- `wasm-bindgen-cli`\n- `wasm-opt`\n- `cargo-deny`\n\nAnd ensure you have added the `wasm32-unknown-unknown` target for rust cross-compilation.\n\nThe various subprojects (the rust code, the wrapper projects) have their own\nbuild instructions, but to run the tests that will be run in CI you can run\n`./scripts/ci/run`.\n\n### For macOS\n\nThese instructions worked to build locally on macOS 13.1 (arm64) as of\nNov 29th 2022.\n\n```bash\n# clone the repo\ngit clone https://github.com/automerge/automerge\ncd automerge\n\n# install rustup\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n\n# install homebrew\n/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n\n# install cmake, node, cmocka\nbrew install cmake node cmocka\n\n# install yarn\nnpm install --global yarn\n\n# install javascript dependencies\nyarn --cwd ./javascript\n\n# install rust dependencies\ncargo install wasm-bindgen-cli wasm-opt cargo-deny\n\n# get nightly rust to produce optimized automerge-c builds\nrustup toolchain install nightly\nrustup component add rust-src --toolchain nightly\n\n# add wasm target in addition to current architecture\nrustup target add wasm32-unknown-unknown\n\n# Run ci script\n./scripts/ci/run\n```\n\nIf your build fails to find `cmocka.h` you may need to teach it about homebrew's\ninstallation location:\n\n```\nexport CPATH=/opt/homebrew/include\nexport LIBRARY_PATH=/opt/homebrew/lib\n./scripts/ci/run\n```\n\n## Nix Flake\n\nIf you have [Nix](https://nixos.org/) installed, there is a flake available with all \nof the dependencies configured and some helper scripts.\n\n``` console\n$ nix develop\n\n  ____                                          _\n / ___|___  _ __ ___  _ __ ___   __ _ _ __   __| |___\n| |   / _ \\| '_ ` _ \\| '_ ` _ \\ / _` | '_ \\ / _` / __|\n| |__| (_) | | | | | | | | | | | (_| | | | | (_| \\__ \\\n \\____\\___/|_| |_| |_|_| |_| |_|\\__,_|_| |_|\\__,_|___/\n\n\nbuild:deno          | Build Deno-wrapped Wasm library\nbuild:host          | Build for aarch64-darwin\nbuild:node          | Build JS-wrapped Wasm library\nbuild:wasi          | Build for Wasm32-WASI\nbuild:wasm:nodejs   | Build for wasm32-unknown-unknown with Node.js bindgings\nbuild:wasm:web      | Build for wasm32-unknown-unknown with web bindings\ndocs:build:host     | Refresh the docs\ndocs:build:wasm     | Refresh the docs with the wasm32-unknown-unknown target\ndocs:open:host      | Open refreshed docs\ndocs:open:wasm      | Open refreshed docs\n# ✂️  SNIP ✂️\n\n$ rustc --version\nrustc 1.82.0 (f6e511eec 2024-10-15) # latest at time of writing\n```\n\n## Contributing\n\nPlease try and split your changes up into relatively independent commits which\nchange one subsystem at a time and add good commit messages which describe what\nthe change is and why you're making it (err on the side of longer commit\nmessages). `git blame` should give future maintainers a good idea of why\nsomething is the way it is.\n\n### Releasing\n\nThere are four artefacts in this repository which need releasing:\n\n* The `@automerge/automerge` NPM package\n* The `@automerge/automerge-wasm` NPM package\n* The automerge deno crate\n* The `automerge` rust crate\n\n#### JS Packages\n\nThe NPM and Deno packages are all released automatically by CI tooling whenever\nthe version number in the respective `package.json` changes. This means that\nthe process for releasing a new JS version is:\n\n1. Bump the version in the `rust/automerge-wasm/package.json` (skip this if there\n   are no new changes to the WASM)\n2. Bump the version of `@automerge/automerge-wasm` we depend on in `javascript/package.json`\n3. Bump the version in `@automerge/automerge` also in `javascript/package.json`\n\nPut all of these bumps in a PR and wait for a clean CI run. Then merge the PR.\nThe CI tooling will pick up a push to `main` with a new version and publish it\nto NPM. This does depend on an access token available as `NPM_TOKEN` in the \nactions environment, this token is generated with a 30 day expiry date so needs\n(manually) refreshing every so often.\n\n#### Rust Package\n\nThis is much easier, but less automatic. The steps to release are:\n\n1. Bump the version in `automerge/Cargo.toml`\n2. Push a PR and merge once clean\n3. Tag the release as `rust/automerge@\u003cversion\u003e`\n4. Push the tag to the repository\n5. Publish the release with `cargo publish`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautomerge%2Fautomerge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fautomerge%2Fautomerge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautomerge%2Fautomerge/lists"}