Supports Access 97 to Microsoft 365
Read .mdb / .accdb files
without Microsoft Access
jetdb reads Microsoft Access databases (.mdb / .accdb) as a CLI tool, a Rust library, and an npm package. Beyond table data, it extracts queries, VBA, macros, and forms. Runs on macOS, Linux, and Windows.
# List the tables
$ jetdb tables jetdb-sample.accdb
# Extract VBA source code
$ jetdb vba show jetdb-sample.accdb modBilling
# Generate DDL for PostgreSQL
$ jetdb schema jetdb-sample.accdb --ddl postgres
No Access, no ODBC driver
Written entirely in Rust, with no dependency on C libraries. If all you have is the .mdb / .accdb file, you can open it as it is. Use it as a CLI or as a Rust library.
macOS, Linux, Windows
Runs even where there is no Windows or Access license.
Access 97 to Microsoft 365
Reads both .mdb and .accdb files, from Jet3 (Access 97) to ACE17 (Access 2019). Files created with Access for Microsoft 365 work too.
Password-protected files
Opens password-protected .accdb files (Agile, RC4 CryptoAPI,
Standard and NonStandard AES) — just add
--password.
Never modifies the original file
Opens files read-only and creates no lock file (.ldb / .laccdb). You can inspect a file someone handed you without worrying about breaking it.
Not just the data, but the whole app
Beyond pulling out tables, it extracts what you need to rebuild an Access application.
Note: Access 97 forms, reports, and VBA are not available. Print settings are shown as raw bytes, not decoded.
-
01Table data
Exports as CSV.
jetdb export jetdb-sample.accdb tblOrdersShow output
OrderID,CustomerID,ProductID,Quantity,OrderDate,Shipped 1,1,1,3,2026-07-03,1 2,2,2,10,2026-07-18,1 3,1,3,1,2026-08-02,1 4,3,1,2,2026-08-25,0 5,2,1,5,2026-09-09,0 -
02Schema
Shows columns, indexes, and relationships.
jetdb schema jetdb-sample.accdb -T tblOrdersShow output
Table: tblOrders Columns: OrderID Long AUTO CustomerID Long NOT NULL ProductID Long NOT NULL Quantity Int NOT NULL OrderDate Timestamp NOT NULL Shipped Boolean Indexes: pkOrders [OrderID ASC] UNIQUE REQUIRED Relationships: fkOrdersCustomers tblOrders.CustomerID -> tblCustomers.CustomerID fkOrdersProducts tblOrders.ProductID -> tblProducts.ProductID -
03DDL
Generates DDL for SQLite, PostgreSQL, MySQL, and Access SQL.
jetdb schema jetdb-sample.accdb -T tblOrders --ddl postgresShow output
CREATE TABLE "tblOrders" ( "OrderID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY, "CustomerID" INTEGER NOT NULL, "ProductID" INTEGER NOT NULL, "Quantity" SMALLINT NOT NULL, "OrderDate" TIMESTAMP WITHOUT TIME ZONE NOT NULL, "Shipped" BOOLEAN, PRIMARY KEY ("OrderID") ); ALTER TABLE "tblOrders" ADD CONSTRAINT "fkOrdersCustomers" FOREIGN KEY ("CustomerID") REFERENCES "tblCustomers" ("CustomerID"); ALTER TABLE "tblOrders" ADD CONSTRAINT "fkOrdersProducts" FOREIGN KEY ("ProductID") REFERENCES "tblProducts" ("ProductID"); -
04Query SQL
Reconstructs the SQL of saved queries.
jetdb queries show jetdb-sample.accdb qryMonthlySalesShow output
SELECT Format(tblOrders.OrderDate, 'yyyy-mm') AS SalesMonth, tblCustomers.CustomerName, Sum(tblOrders.Quantity * tblProducts.UnitPrice) AS Total FROM (tblOrders INNER JOIN tblCustomers ON tblOrders.CustomerID = tblCustomers.CustomerID) INNER JOIN tblProducts ON tblOrders.ProductID = tblProducts.ProductID GROUP BY Format(tblOrders.OrderDate, 'yyyy-mm'), tblCustomers.CustomerName ORDER BY Format(tblOrders.OrderDate, 'yyyy-mm'), tblCustomers.CustomerName; -
05VBA
Extracts the source code of standard modules, class modules, and the modules of forms and reports.
jetdb vba show jetdb-sample.accdb modBillingShow output
Attribute VB_Name = "modBilling" Option Compare Database Option Explicit Public Const TAX_RATE As Double = 0.1 ' Returns the amount of one order line, tax included. Public Function LineTotal(ByVal Quantity As Long, ByVal unitPrice As Currency) As Currency LineTotal = Quantity * unitPrice * (1 + TAX_RATE) End Function ' Returns the amount of an order, tax included, or 0 if there is no such order. Public Function OrderTotal(ByVal OrderID As Long) As Currency Dim rs As DAO.Recordset Set rs = CurrentDb.OpenRecordset( _ "SELECT o.Quantity, p.UnitPrice FROM tblOrders AS o INNER JOIN tblProducts AS p " & _ … -
06Macros
Shows named macros, embedded macros in forms and reports, and data macros on tables, as SaveAsText text. The command below shows a named macro; use
macro embeddedfor a form or report andmacro datafor a table.jetdb macro show jetdb-sample.accdb mcrOpenOrdersShow output
Version =196611 PublishOption =1 ColumnsShown =0 Begin Comment ="_AXL:<?xml version='1.0' encoding='UTF-16' standalone='no'?><UserInterfaceMacro " "xmlns='http://schemas.microsoft.com/office/accessservices/2009/11/application'><" "Statements><Action Name='OpenForm'><Argument " End Begin Comment ="_AXL:Name='FormName'>frmOrders</Argument></Action><Action Name='MessageBox'><Arg" "ument Name='Message'>Showing the orders.</Argument><Argument Name='Type'>Informa" "tion</Argument><Argument Name='Title'>Sales</" End Begin Comment ="_AXL:Argument></Action></Statements></UserInterfaceMacro>" End -
07Forms and reports
Shows the properties of forms and reports, and of their controls.
jetdb form props jetdb-sample.accdb frmOrdersShow output
Form: frmOrders Form Properties: … RecordSource tblOrders Caption Orders … … Control: txtQuantity (TextBox) OverlapFlags 85 Left 1800 Top 1560 Width 2400 Height 300 TabIndex 3 Name txtQuantity ControlSource Quantity StatusBarText Number of units … … Control: btnShowTotal (CommandButton) OverlapFlags 85 Left 1800 Top 2940 Width 2400 Height 400 TabIndex 6 Name btnShowTotal Caption Show total OnClick [Event Procedure] … -
08Properties
Shows the properties of objects such as tables and queries.
jetdb prop jetdb-sample.accdb tblProductsShow output
Object: tblProducts Table Properties: Description "Products for sale" Column: ProductName Required yes Column: UnitPrice Description "Price per unit, tax excluded" Column: Discontinued Description "No longer sold"
Compared with other tools
| Feature | jetdb0.4.0 | MDB Tools1.0.1 | Jackcess5.0.3 / fork 5.1.7 | mdb-reader3.2.0 |
|---|---|---|---|---|
| Language | Rust | C | Java | TypeScript |
| License | MIT or Apache-2.0 | LGPL (library), GPL (CLI) | Apache-2.0 | MIT |
| Both .mdb and .accdb | ○ | ○ | ○ | ○ |
| VBA extraction | ○ | × | × | × |
| Named macros | ○ | × | × | × |
| Embedded macros (forms/reports) | ○ | × | × | × |
| Data macros (tables) | ○ | × | × | × |
| Form/report definitions | ○ | × | × | × |
| Query SQL | ○ | △ | ○ | × |
| DDL generation | ○ | ○ | × | × |
| Attachment contents | ○ | × | ○ | ○ |
| Password-protected .accdb | ○ | × | △ | △ |
| CLI | ○ | ○ | × | × |
| Runs in the browser | ○ | × | × | ○ |
| Writing | × | △ | ○ | × |
○ Supported △ Partial or conditional × Not supported
○ means usable with Access 2000 and later. Exceptions that apply only to Access 97 are in the notes.
- MDB Tools reconstructs only SELECT queries (no JOIN or GROUP BY).
- Jackcess opens password-protected .accdb files with the separate Jackcess Encrypt library. For the items in this table, the original Jackcess and the fork give the same results.
- The MDB Tools library is LGPL-2.0 or later, and its CLI is GPL-2.0 or later.
- mdb-reader does not support Standard AES encryption for password-protected .accdb files.
- jetdb cannot read Access 97 form/report definitions or VBA.
- MDB Tools can only add and update rows, through its library API.
- Jackcess writes to Access 2000 and later; Access 97 files are read-only.
Surveyed on 2026-10-11 (the latest release of each tool)
Ready to hand to AI agents
With the jetdb CLI installed, add the jetdb Skill and AI agents can read Access files with jetdb. Ask “I want to move this .accdb to PostgreSQL”, and the agent reads everything from the table definitions to the queries, VBA, and forms, and works through the migration.
Claude Code
Install it from the Plugin Marketplace.
/plugin marketplace add dominion525/agent-skills
/plugin install jetdb-cli@dominion525-skills
Other agents
Install it with the skills CLI. It supports Codex, Cursor, OpenCode, and more, and you choose where to install it when you run it.
npx skills add dominion525/agent-skills --skill jetdb-cli
Even without the Skill, the CLI suits AI
- Plain text output: CSV, SQL, VBA source, and so on, in forms that are easy to read and process.
- Stable ordering: Lists are sorted by name. The same file always gives the same result.
-
Empty is not an error: When there are no tables
or queries, it exits successfully with empty output. Errors go to
standard error as a single line starting with
jetdb:.
Runs in the browser, too
With the WebAssembly build (the npm package
jetdb-wasm), browsers and Node.js can read the same
things as the CLI: tables, queries, VBA, macros, forms,
properties, and DDL, including password-protected files. Files
never leave the browser. See the
JavaScript API for how to use it.
Install
Install the CLI
Prebuilt binaries
Download the file for your platform from GitHub Releases and extract it.
Homebrew
brew install dominion525/tap/jetdb
cargo
If you have Rust installed, install it from crates.io.
cargo install jetdb-cli
Use it as a library
Rust
Add it from crates.io. See the library documentation and docs.rs for how to use it.
cargo add jetdb
JavaScript (browser / Node.js)
Install the WebAssembly build from npm. See the JavaScript API for how to use it.
npm install jetdb-wasm