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 tblOrders
    Show 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 tblOrders
    Show 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 postgres
    Show 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 qryMonthlySales
    Show 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 modBilling
    Show 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 embedded for a form or report and macro data for a table.

    jetdb macro show jetdb-sample.accdb mcrOpenOrders
    Show 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 frmOrders
    Show 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 tblProducts
    Show 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.

All releases

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