{"id":30110288,"url":"https://github.com/tinyplex/synclets","last_synced_at":"2026-01-04T01:18:24.084Z","repository":{"id":307343064,"uuid":"1028690305","full_name":"tinyplex/synclets","owner":"tinyplex","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-07T23:12:43.000Z","size":799,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-08T01:07:23.703Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tinyplex.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2025-07-29T23:18:33.000Z","updated_at":"2025-08-07T23:12:46.000Z","dependencies_parsed_at":"2025-07-30T20:27:17.589Z","dependency_job_id":"4550c288-3a74-4801-87ba-9960255f7e4a","html_url":"https://github.com/tinyplex/synclets","commit_stats":null,"previous_names":["tinyplex/synclets"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tinyplex/synclets","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyplex%2Fsynclets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyplex%2Fsynclets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyplex%2Fsynclets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyplex%2Fsynclets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tinyplex","download_url":"https://codeload.github.com/tinyplex/synclets/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyplex%2Fsynclets/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269606205,"owners_count":24446137,"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","status":"online","status_checked_at":"2025-08-09T02:00:10.424Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":"2025-08-10T04:23:24.689Z","updated_at":"2026-01-04T01:18:24.073Z","avatar_url":"https://github.com/tinyplex.png","language":"TypeScript","readme":"\u003clink rel=\"preload\" as=\"image\" href=\"https://synclets.org/pglite.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://synclets.org/sqlite.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://tinybase.org/favicon.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://synclets.org/browser.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://synclets.org/filesystem.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://synclets.org/memory.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://synclets.org/websockets.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://synclets.org/broadcast.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://tinywidgets.org/favicon.svg?asImg\"\u003e\u003clink rel=\"preload\" as=\"image\" href=\"https://tinytick.org/favicon.svg?asImg\"\u003e\u003csection id=\"hero\"\u003e\u003ch2 id=\"an-open-storage-agnostic-sync-engine-development-kit\"\u003eAn open, storage-agnostic, \u003cem\u003esync engine\u003c/em\u003e development kit.\u003c/h2\u003e\u003c/section\u003e\u003cp\u003e\u003ca class=\"start\" href=\"https://synclets.org/guides/releases/#introducing-synclets\"\u003eIntroducing Synclets\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003cspan id=\"one-with\"\u003eRead about this new project!\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://synclets.org/guides/the-basics/core-concepts\"\u003eCore concepts\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://synclets.org/api/synclets\"\u003eRead the docs\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://github.com/tinyplex/synclets\"\u003eRead the code\u003c/a\u003e\u003c/p\u003e\u003chr\u003e\u003csection\u003e\u003ch2 id=\"what-are-synclets\"\u003eWhat are Synclets?\u003c/h2\u003e\u003cp\u003eSynclets are intended to make it easy to synchronize data between the different parts of your applications, whether between local storage and remote servers, between different devices, or even across worker boundaries.\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2 id=\"why-synclets\"\u003eWhy Synclets?\u003c/h2\u003e\u003cp\u003eWe believe synchronization is a fundamental part of modern app development, especially in the context of rich client and local-first apps. We also believe that you shouldn\u0026#x27;t be locked into a specific storage solution, transport layer, or vendor in order to do so!\u003c/p\u003e\u003c/section\u003e\u003csection class=\"logos\"\u003e\u003ch2 id=\"store-your-data-in\"\u003eStore your data in...\u003c/h2\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/connector-database-pglite\"\u003e\u003cimg src=\"https://synclets.org/pglite.svg?asImg\" width=\"48\"\u003e PGlite\u003c/a\u003e\u003c/div\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/connector-database-sqlite3\"\u003e\u003cimg src=\"https://synclets.org/sqlite.svg?asImg\" width=\"48\"\u003e SQLite\u003c/a\u003e\u003c/div\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/connector-tinybase\"\u003e\u003cimg src=\"https://tinybase.org/favicon.svg?asImg\" width=\"48\"\u003e TinyBase\u003c/a\u003e\u003c/div\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/connector-browser\"\u003e\u003cimg src=\"https://synclets.org/browser.svg?asImg\" width=\"48\"\u003e Browser\u003c/a\u003e\u003c/div\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/connector-fs\"\u003e\u003cimg src=\"https://synclets.org/filesystem.svg?asImg\" width=\"48\"\u003e Files\u003c/a\u003e\u003c/div\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/connector-memory\"\u003e\u003cimg src=\"https://synclets.org/memory.svg?asImg\" width=\"48\"\u003e Memory\u003c/a\u003e\u003c/div\u003e\u003c/section\u003e\u003csection class=\"logos\"\u003e\u003ch2 id=\"and-synchronize-it-over\"\u003e...and synchronize it over:\u003c/h2\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/transport-ws/\"\u003e\u003cimg src=\"https://synclets.org/websockets.svg?asImg\" width=\"48\"\u003e WebSockets\u003c/a\u003e\u003c/div\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/transport-broadcast-channel/\"\u003e\u003cimg src=\"https://synclets.org/broadcast.svg?asImg\" width=\"48\"\u003e Broadcast\u003c/a\u003e\u003c/div\u003e\u003cdiv\u003e\u003ca href=\"https://synclets.org/api/transport-memory\"\u003e\u003cimg src=\"https://synclets.org/memory.svg?asImg\" width=\"48\"\u003e Memory\u003c/a\u003e\u003c/div\u003e\u003c/section\u003e\u003csection\u003e\u003ch2 id=\"connect-to-a-data-store\"\u003eConnect to a data store\u003c/h2\u003e\u003cp\u003eSynclets are designed to work with lots of different flavors of storage and transport. For example, you can easily connect to a local instance of PGlite.\u003c/p\u003e\u003c/section\u003e\n\n```js\nimport {PGlite} from '@electric-sql/pglite';\nimport {createPgliteDataConnector} from 'synclets/pglite';\n\nconst pglite = await PGlite.create();\nconst dataConnector = createPgliteDataConnector({\n  depth: 1,\n  pglite,\n});\n```\n\n\u003csection\u003e\u003ch2 id=\"metadata-is-stored-separately\"\u003eMetadata is stored separately\u003c/h2\u003e\u003cp\u003eYou can store metadata about your data (primarily timestamps) separately, or in the same data store. For example, here we\u0026#x27;re using PGlite for metadata too.\u003c/p\u003e\u003c/section\u003e\n\n```js\nimport {createPgliteMetaConnector} from 'synclets/pglite';\n\nconst metaConnector = createPgliteMetaConnector({\n  depth: 1,\n  pglite,\n});\n```\n\n\u003csection\u003e\u003ch2 id=\"pick-a-transport-layer\"\u003ePick a transport layer\u003c/h2\u003e\u003cp\u003eSynclets are designed to work over a variety of transport layers. For example, to use WebSockets via a server use the \u003ca href=\"https://synclets.org/api/ws/functions/transport/createwsclienttransport/\"\u003e\u003ccode\u003ecreateWsClientTransport\u003c/code\u003e\u003c/a\u003e function.\u003c/p\u003e\u003c/section\u003e\n\n```js\nimport {createWsClientTransport} from 'synclets/ws';\nimport {WebSocket} from 'ws';\n\nconst transport = createWsClientTransport({\n  webSocket: new WebSocket(\n    'wss://demo.synclets.org/room1',\n  ),\n});\n```\n\n\u003csection\u003e\u003ch2 id=\"and-then-put-it-all-together\"\u003eAnd then put it all together\u003c/h2\u003e\u003cp\u003eFinally compose a \u003ca href=\"https://synclets.org/api/synclets/interfaces/core/synclet/\"\u003e\u003ccode\u003eSynclet\u003c/code\u003e\u003c/a\u003e instance with your chosen data connector, meta connector, and transport - and start it!\u003c/p\u003e\u003cp\u003eWe\u0026#x27;re good to go.\u003c/p\u003e\u003cp\u003eTake a look at \u003ca href=\"http://localhost:8082/guides/releases/#how-do-synclets-work\"\u003ethe sample\u003c/a\u003e in our launch announcement for a working example.\u003c/p\u003e\u003c/section\u003e\n\n```js\nimport {createSynclet} from 'synclets';\n\nconst synclet = await createSynclet({\n  dataConnector,\n  metaConnector,\n  transport,\n});\nawait synclet.start();\n\n// ...\n\nawait synclet.destroy();\n```\n\n\u003csection\u003e\u003ch2 id=\"what-next\"\u003eWhat next?\u003c/h2\u003e\u003cp\u003eThe Synclets project is pre-alpha right now, so there is still plenty of work to be done! There are decent test suites in place for the core components, and some basic documentation, but we still need to build out more connectors, transports, and examples.\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2 id=\"please-follow-along\"\u003ePlease follow along!\u003c/h2\u003e\u003cp\u003eWe hope you like the idea of this project! If so, please follow us on \u003ca href=\"https://github.com/tinyplex/synclets\"\u003eGitHub\u003c/a\u003e, \u003ca href=\"https://x.com/syncletsjs\"\u003eX\u003c/a\u003e, or \u003ca href=\"https://bsky.app/profile/synclets.bsky.social\"\u003eBlueSky\u003c/a\u003e, and stay tuned for future updates as we continue to develop Synclets further.\u003c/p\u003e\u003cp\u003eAlso feel free to kick the tires on our very basic \u003ca href=\"https://github.com/tinyplex/vite-synclets\"\u003eVite template\u003c/a\u003e.\u003c/p\u003e\u003c/section\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://synclets.org/guides/the-basics/core-concepts\"\u003eCore concepts\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://synclets.org/api/synclets\"\u003eRead the docs\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://github.com/tinyplex/synclets\"\u003eRead the code\u003c/a\u003e\u003c/p\u003e\u003chr\u003e\u003csection id=\"family\"\u003e\u003ch2 id=\"meet-the-family\"\u003eMeet the family\u003c/h2\u003e\u003cp\u003eThe Synclets project is part of a group of libraries designed to help make rich client and local-first apps easier to build. Check out the others:\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://tinybase.org\" target=\"_blank\"\u003e\u003cimg src=\"https://tinybase.org/favicon.svg?asImg\" width=\"48\"\u003e\u003cbr\u003e\u003cb\u003eTinyBase\u003c/b\u003e\u003c/a\u003e\u003cbr\u003eA reactive data store and sync engine.\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://tinywidgets.org\" target=\"_blank\"\u003e\u003cimg src=\"https://tinywidgets.org/favicon.svg?asImg\" width=\"48\"\u003e\u003cbr\u003e\u003cb\u003eTinyWidgets\u003c/b\u003e\u003c/a\u003e\u003cbr\u003eA collection of tiny, reusable, UI components.\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://tinytick.org\" target=\"_blank\"\u003e\u003cimg src=\"https://tinytick.org/favicon.svg?asImg\" width=\"48\"\u003e\u003cbr\u003e\u003cb\u003eTinyTick\u003c/b\u003e\u003c/a\u003e\u003cbr\u003eA tiny but very useful task orchestrator.\u003c/p\u003e\u003c/section\u003e","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinyplex%2Fsynclets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinyplex%2Fsynclets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinyplex%2Fsynclets/lists"}