{"id":13721945,"url":"https://github.com/keeweb/kdbxweb","last_synced_at":"2025-05-14T23:04:50.239Z","repository":{"id":36147127,"uuid":"40451143","full_name":"keeweb/kdbxweb","owner":"keeweb","description":"Web Kdbx library","archived":false,"fork":false,"pushed_at":"2024-12-24T00:19:17.000Z","size":4313,"stargazers_count":433,"open_issues_count":11,"forks_count":57,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-05-07T00:35:33.601Z","etag":null,"topics":["kdbx","keepass","keeweb","password-manager"],"latest_commit_sha":null,"homepage":"https://app.keeweb.info","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/keeweb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"antelle","patreon":null,"open_collective":"keeweb","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2015-08-09T21:28:11.000Z","updated_at":"2025-04-16T09:08:19.000Z","dependencies_parsed_at":"2025-04-12T15:51:41.620Z","dependency_job_id":null,"html_url":"https://github.com/keeweb/kdbxweb","commit_stats":{"total_commits":398,"total_committers":8,"mean_commits":49.75,"dds":"0.047738693467336724","last_synced_commit":"9b86a035a53f1827e427a0fc081bdcccc24f4f1b"},"previous_names":["antelle/kdbxweb"],"tags_count":90,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keeweb%2Fkdbxweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keeweb%2Fkdbxweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keeweb%2Fkdbxweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keeweb%2Fkdbxweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keeweb","download_url":"https://codeload.github.com/keeweb/kdbxweb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243358,"owners_count":22038046,"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":["kdbx","keepass","keeweb","password-manager"],"created_at":"2024-08-03T01:01:22.996Z","updated_at":"2025-05-14T23:04:45.215Z","avatar_url":"https://github.com/keeweb.png","language":"TypeScript","funding_links":["https://github.com/sponsors/antelle","https://opencollective.com/keeweb"],"categories":["API libraries","TypeScript"],"sub_categories":["Other clients"],"readme":"# KdbxWeb ![CI Checks](https://github.com/keeweb/kdbxweb/workflows/CI%20Checks/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/keeweb/kdbxweb/badge.svg?branch=master)](https://coveralls.io/github/keeweb/kdbxweb?branch=master)\n\nKdbxWeb is a high-performance javascript library for reading/writing KeePass v2 databases (kdbx) in node.js or browser.\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n- [KdbxWeb  ](#kdbxweb--)\n  - [Features](#features)\n  - [Browser support](#browser-support)\n  - [Compatibility](#compatibility)\n  - [Kdbx4](#kdbx4)\n  - [Usage](#usage)\n    - [Loading](#loading)\n    - [Saving](#saving)\n    - [File info](#file-info)\n    - [Changing Credentials](#changing-credentials)\n    - [Creation](#creation)\n    - [Maintenance](#maintenance)\n    - [Merge](#merge)\n    - [Groups](#groups)\n    - [Group Creation](#group-creation)\n    - [Group Deletion](#group-deletion)\n    - [Group Move](#group-move)\n    - [Recycle Bin](#recycle-bin)\n    - [Recursive Traverse](#recursive-traverse)\n    - [Entries](#entries)\n    - [Entry Creation](#entry-creation)\n    - [Entry Modification](#entry-modification)\n    - [Entry Deletion](#entry-deletion)\n    - [Entry Move](#entry-move)\n    - [ProtectedValue](#protectedvalue)\n    - [Errors](#errors)\n    - [Consts](#consts)\n    - [Random](#random)\n    - [ByteUtils](#byteutils)\n  - [Building](#building)\n  - [3rd party libs](#3rd-party-libs)\n  - [Tools](#tools)\n  - [See it in action](#see-it-in-action)\n  - [Extras](#extras)\n  - [License](#license)\n\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Features\n\nkdbxweb offers the following feature sets:\n\n- runs in browser or node.js\n- no native addons\n- fast encryption with WebCrypto\n- total ≈130kB with dependencies\n- full support of Kdbx features\n- protected values are stored in memory XOR'ed\n- conflict-free merge support\n- high code coverage\n- strict TypeScript\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Browser support\n\n- All modern browsers\n  - Chrome / Chromium\n  - Firefox\n  - Safari\n  - Opera\n  - Edge\n- NodeJS\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Compatibility\n\nSupported formats are Kdbx3 and Kdbx4, current KeePass file format. Old kdb files (for KeePass v1) are out of scope of this library. We currently have no plans to support the older formats.\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Kdbx4\n\nKdbx4 has introduced Argon2, a new hashing function. Due to complex calculations, you have to implement it manually and export to kdbxweb, if you want to support such files. Here's how:\n\n```ts\nkdbxweb.CryptoEngine.setArgon2Impl((password, salt,\n    memory, iterations, length, parallelism, type, version\n) =\u003e {\n    // your implementation makes hash (Uint8Array, 'length' bytes)\n    return Promise.resolve(hash);\n});\n```\n\nYou can find an implementation example in [tests](https://github.com/keeweb/kdbxweb/blob/master/test/test-support/argon2.ts).  \n\nIt's not compiled into the library because there's no universal way to provide a fast implementation, so it's up to you to choose the best one.\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Usage\n\nThis section gives usage examples on how you can implement kdbxweb into your project.\n\n\u003cbr /\u003e\n\n### Loading\n\n```ts\nlet credentials = new kdbxweb.Credentials(kdbxweb.ProtectedValue.fromString('demo'),\n    keyFileArrayBuffer, challengeResponseFunction);\nconst db1 = await kdbxweb.Kdbx.load(dataAsArrayBuffer, credentials);\nconst db2 = await kdbxweb.Kdbx.loadXml(dataAsString, credentials);\n```\n\n### Saving\n\n```ts\nconst dataAsArrayBuffer = await db.save();\nconst xmlAsString = await db.saveXml();\n```\n\nYou can also pretty-print XML:\n```ts\nconst prettyPrintedXml = await db.saveXml(true);\n```\n\n\u003cbr /\u003e\n\n### File info\n\n```ts\ndb.header\ndb.meta\n```\n\nSee the corresponding type fields inside, they should be obvious.\n\n### Changing Credentials\n\n```ts\nconst db = await kdbxweb.Kdbx.load(data, credentials);\ndb.credentials.setPassword(kdbxweb.ProtectedValue.fromString('newPass'));\nconst randomKeyFile = await kdbxweb.Credentials.createRandomKeyFile();\ndb.credentials.setKeyFile(randomKeyFile);\nawait db.save();\n```\n\n### Creation\n\n```ts\nlet newDb = kdbxweb.Kdbx.create(credentials, 'My new db');\nlet group = newDb.createGroup(newDb.getDefaultGroup(), 'subgroup');\nlet entry = newDb.createEntry(group);\n```\n\n\u003cbr /\u003e\n\n### Maintenance\n\n```ts\ndb.cleanup({\n    historyRules: true,\n    customIcons: true,\n    binaries: true\n});\n\n// upgrade the db to latest version (currently KDBX4)\ndb.upgrade();\n\n// downgrade to KDBX3\ndb.setVersion(3);\n\n// set KDF to AES\ndb.setKdf(kdbxweb.Consts.KdfId.Aes);\n```\n\n\u003cbr /\u003e\n\n### Merge\n\nEntries, groups and meta are consistent against merging in any direction with any state.  \nDue to format limitations, p2p entry history merging and some non-critical fields in meta can produce phantom records or deletions, \nso correct entry history merging is supported only with one central replica. Items order is not guaranteed but the algorithm tries to preserve it.\n\n```ts\nlet db = await kdbxweb.Kdbx.load(data, credentials); // load local db\n// work with db\ndb.save(); // save local db\nlet editStateBeforeSave = db.getLocalEditState(); // save local editing state (serializable to JSON)\ndb.close(); // close local db\n\ndb = kdbxweb.Kdbx.load(data, credentials); // reopen it again\ndb.setLocalEditState(editStateBeforeSave); // assign edit state obtained before save\n\n// work with db\nlet remoteDb = await kdbxweb.Kdbx.load(remoteData, credentials); // load remote db\ndb.merge(remoteDb); // merge remote into local\ndelete remoteDb; // don't use remoteDb anymore\n\nlet saved = await db.save(); // save local db\neditStateBeforeSave = db.getLocalEditState(); // save local editing state again\n\nlet pushedOk = pushToUpstream(saved); // push db to upstream\nif (pushedOk) {\n    db.removeLocalEditState(); // clear local editing state\n    editStateBeforeSave = null; // and discard it\n}\n```\n\n\u003cbr /\u003e\n\n### Groups\n\n```ts\nlet defaultGroup = db.getDefaultGroup();\nlet anotherGroup = db.getGroup(uuid);\nlet deepGroup = defaultGroup.groups[1].groups[2];\n```\n\n\u003cbr /\u003e\n\n### Group Creation\n\n```ts\nlet group = db.createGroup(db.getDefaultGroup(), 'New group');\nlet anotherGroup = db.createGroup(group, 'Subgroup');\n```\n\n\u003cbr /\u003e\n\n### Group Deletion\n\n```ts\ndb.remove(group);\n```\n\n\u003cbr /\u003e\n\n### Group Move\n\n```ts\ndb.move(group, toGroup);\ndb.move(group, toGroup, atIndex);\n```\n\n\u003cbr /\u003e\n\n### Recycle Bin\n\n```ts\nlet recycleBin = db.getGroup(db.meta.recycleBinUuid);\nif (!recycleBin) {\n    db.createRecycleBin();\n}\n```\n\n\u003cbr /\u003e\n\n### Recursive Traverse\n\n```ts\nfor (const entry of group.allEntries()) { /* ... */ }\nfor (const group of group.allGroups()) { /* ... */ }\nfor (const entryOrGroup of group.allGroupsAndEntries()) { /* ... */ }\n```\n\n\u003cbr /\u003e\n\n### Entries\n\n```ts\nlet entry = db.getDefaultGroup().entries[0];\nentry.fields.AccountNumber = '1234 5678';\nentry.fields.Pin = kdbxweb.ProtectedValue.fromString('4321');\n```\n\n\u003cbr /\u003e\n\n### Entry Creation\n\n```ts\nlet entry = db.createEntry(group);\n```\n\n\u003cbr /\u003e\n\n### Entry Modification\n\n```ts\n// push current state to history stack\nentry.pushHistory();\n\n// change something\nentry.fgColor = '#ff0000';\n\n// update entry modification and access time\nentry.times.update();\n\n// remove states from entry history\nentry.removeHistory(index, count);\n```\n\n\u003cbr /\u003e\n\n\u003e [!WARNING]\n\u003e Do **not** modify history states directly; this will break merge.\n\n\u003cbr /\u003e\n\n### Entry Deletion\n\n```ts\ndb.remove(entry);\n```\n\n\u003cbr /\u003e\n\n### Entry Move\n\n```ts\ndb.move(entry, toGroup);\n```\n\nIf you're moving an entry from another file, this is called _import_:\n\n```ts\ndb.importEntry(entry, toGroup, sourceFile);\n```\n\n\u003cbr /\u003e\n\n### ProtectedValue\n\nUsed for passwords and custom fields, stored the value in memory XOR'ed\n\n```ts\nlet value = new kdbxweb.ProtectedValue(xoredByted, saltBytes);\nlet valueFromString = kdbxweb.ProtectedValue.fromString('str');\nlet valueFromBinary = kdbxweb.ProtectedValue.fromBinary(data);\nlet textString = value.getText();\nlet binaryData = value.getBinary();\nlet includesSubString = value.includes('foo');\n```\n\n\u003cbr /\u003e\n\n### Errors\n\n```ts\ntry {\n    await kdbxweb.Kdbx.load(data, credentials);\n} catch (e) {\n    if (e instanceof kdbxweb.KdbxError \u0026\u0026 e.code === kdbxweb.Consts.ErrorCodes.BadSignature) {\n        /* ... */\n    }\n}\n```\n\n\u003cbr /\u003e\n\n### Consts\n\n[Consts definition](https://github.com/keeweb/kdbxweb/blob/master/lib/defs/consts.ts)  \n\n```ts\nkdbxweb.Consts.ErrorCodes // all thrown errors have code property\nkdbxweb.Consts.Defaults // default db settings\nkdbxweb.Consts.Icons // icons map\n```\n\n\u003cbr /\u003e\n\n### Random\n\n```ts\nlet randomArray = kdbxweb.Crypto.random(/* desired length */ 100);\n```\n\n\u003cbr /\u003e\n\n### ByteUtils\n\n```ts\nkdbxweb.ByteUtils.bytesToString(bytes);\nkdbxweb.ByteUtils.stringToBytes(str);\nkdbxweb.ByteUtils.bytesToBase64(bytes);\nkdbxweb.ByteUtils.base64ToBytes(str);\nkdbxweb.ByteUtils.bytesToHex(bytes);\nkdbxweb.ByteUtils.hexToBytes(str);\n```\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Building\n\n\u003e [!NOTE]\n\u003e This project requires node v18.18.0.\n\n\u003cbr /\u003e\n\nUse npm to build this project:\n\n```sh\nnpm run build\n```  \n\n\u003cbr /\u003e\n\nTo run tests:\n\n```sh\nnpm test\n```  \n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## 3rd party libs\n\nkdbxweb includes these 3rd party libraries:\n- [fflate](https://github.com/101arrowz/fflate)\n- [xmldom](https://github.com/xmldom/xmldom)\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Tools\n\nThe library provides a number of scripts to work with KDBX files:\n\nDump the binary header:\n\n```sh\nnpm run script:dump-header my-db.kdbx\n```\n\n\u003cbr /\u003e\n\nPrint detailed size information about internal objects:\n\n```sh\nnpm run script:kdbx-size-profiler my-db.kdbx password\n```\n\n\u003cbr /\u003e\n\nDump the internal XML:\n\n```sh\nnpm run script:kdbx-to-xml my-db.kdbx password\n```\n\n\u003cbr /\u003e\n\nGenerate big files for load testing:\n\n```sh\nnpm run script:make-big-files\n```\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## See it in action\n\nThis library is used in **[KeeWeb](https://app.keeweb.info)**\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## Extras\n\nWe also provide a template for **[HexFiend](https://github.com/ridiculousfish/HexFiend)** to explore the contents of KDBX files, you can find it **[here](format)**.\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeeweb%2Fkdbxweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeeweb%2Fkdbxweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeeweb%2Fkdbxweb/lists"}