npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

libflatpak

v1.0.0

Published

JS bindings for libflatpak

Readme

libflatpak-js

JavaScript bindings for libflatpak, providing full access to Flatpak installation management, remote repositories, application installation, and system information from Node.js.

Features

  • Full API Coverage: All 11 Flatpak GObject classes with methods and properties
  • Automatic Type Conversion: GPtrArray → JavaScript arrays with element wrapping
  • Nullable Parameter Support: Optional parameters accept null/undefined
  • Memory Management: Automatic cleanup of native resources
  • Inheritance Support: JavaScript classes reflect GObject inheritance hierarchy

Installation

npm install libflatpak

Prerequisites:

  • Flatpak development libraries (flatpak-devel package on Fedora/RHEL, libflatpak-dev on Debian/Ubuntu)
  • Node.js 14 or later
  • C++ build tools (for native module compilation)

Quick Start

Basic System Information

const { getDefaultArch, getSystemInstallations } = require("libflatpak");

// Get system information
const arch = getDefaultArch();
console.log(`Default architecture: ${arch}`);

// Get available installations
const installations = getSystemInstallations();
console.log(`Found ${installations.length} installation(s)`);

if (installations.length > 0) {
    const installation = installations[0];
    console.log(`Installation ID: ${installation.getId()}`);
    console.log(`Is user installation: ${installation.getIsUser()}`);
}

Working with Installations

const { getSystemInstallations } = require("libflatpak");

// Get available installations
const installations = getSystemInstallations();
console.log(`Found ${installations.length} installation(s)`);

if (installations.length === 0) {
    console.error("No system installation found");
    process.exit(1);
}

const installation = installations[0];

// List installed applications
console.log("\nListing installed applications...");
try {
    const installedRefs = installation.listInstalledRefs();
    console.log(`Found ${installedRefs.length} installed applications:`);

    installedRefs.forEach((ref, index) => {
        console.log(`${index + 1}. ${ref.getName()} (${ref.getKind()})`);
    });
} catch (error) {
    console.error(`Error listing installed refs: ${error.message}`);
}

// List available remotes
console.log("\nListing available remotes...");
try {
    const remotes = installation.listRemotes();
    console.log(`Found ${remotes.length} remotes:`);

    remotes.forEach((remote) => {
        console.log(`- ${remote.getName()}: ${remote.getUrl()}`);
    });
} catch (error) {
    console.error(`Error listing remotes: ${error.message}`);
}

Advanced Examples

Example 1: Adding a Remote Repository

const { getSystemInstallation, Remote } = require("libflatpak");

async function addFlathubRemote() {
    const installation = getSystemInstallation();
    if (!installation) {
        throw new Error("No system installation available");
    }

    try {
        // Create a new remote object
        const remote = Remote.create("flathub");

        // Configure the remote
        remote.setUrl("https://dl.flathub.org/repo/");
        remote.setTitle("Flathub");
        remote.setComment("The central repository for Flatpak applications");
        remote.setGpgVerify(true);
        remote.setNoenumerate(false);
        remote.setDisabled(false);

        // Add the remote to the installation
        const added = installation.addRemote(remote, false, null);
        if (added) {
            console.log("Successfully added Flathub remote");

            // Update remote metadata
            const updated = installation.updateRemoteSync("flathub", null);
            if (updated) {
                console.log("Remote metadata updated successfully");
            }
        } else {
            console.log("Remote already exists or addition failed");
        }

        remote.free();
    } finally {
        installation.free();
    }
}

addFlathubRemote().catch(console.error);

Example 2: Installing a Package

const { getSystemInstallation, Transaction } = require("libflatpak");
const https = require("https"); // or const http = require('http')

async function fetchFlatpakref(url) {
    return new Promise((resolve, reject) => {
        https
            .get(url, (response) => {
                if (response.statusCode !== 200) {
                    reject(
                        new Error(
                            `Failed to fetch flatpakref: ${response.statusCode}`,
                        ),
                    );
                    return;
                }

                const chunks = [];
                response.on("data", (chunk) => chunks.push(chunk));
                response.on("end", () => {
                    const buffer = Buffer.concat(chunks);
                    resolve(buffer);
                });
                response.on("error", reject);
            })
            .on("error", reject);
    });
}

async function installApplication(appId) {
    const installation = getSystemInstallation();
    if (!installation) {
        throw new Error("No system installation available");
    }

    try {
        // Download the .flatpakref file
        const flatpakrefUrl = `https://dl.flathub.org/repo/appstream/${appId}.flatpakref`;
        console.log(`Downloading ${flatpakrefUrl}...`);

        const flatpakrefData = await fetchFlatpakref(flatpakrefUrl);

        // Create a transaction for this installation
        const transaction = Transaction.create(installation, null);

        // Configure transaction options
        transaction.setNoInteraction(false);
        transaction.setAutoInstallSdk(true);

        // Add the application to install
        // flatpakrefData is a Buffer containing the .flatpakref file
        const added = transaction.addInstallFlatpakref(flatpakrefData);

        if (!added) {
            throw new Error(`Failed to add installation for ${appId}`);
        }

        console.log(`Starting installation of ${appId}...`);

        // Run the transaction
        const success = transaction.run(null);

        if (success) {
            console.log(`Successfully installed ${appId}`);

            // Get the installed ref
            const installedRef = installation.getInstalledRef(
                0, // FLATPAK_REF_KIND_APP
                appId,
                "x86_64",
                "stable",
                null,
            );

            if (installedRef) {
                console.log(
                    `Installed version: ${installedRef.getAppdataVersion()}`,
                );
                installedRef.free();
            }
        } else {
            console.error(`Failed to install ${appId}`);
        }

        transaction.free();
    } finally {
        installation.free();
    }
}

// Alternative: Install from a local .flatpakref file
async function installFromLocalFile(filePath) {
    const { readFileSync } = require("fs");
    const installation = getSystemInstallation();
    if (!installation) {
        throw new Error("No system installation available");
    }

    try {
        // Read local .flatpakref file
        const flatpakrefData = readFileSync(filePath);

        const transaction = Transaction.create(installation, null);
        transaction.setNoInteraction(false);

        const added = transaction.addInstallFlatpakref(flatpakrefData);

        if (added) {
            const success = transaction.run(null);
            if (success) {
                console.log("Installation from local file completed");
            }
        }

        transaction.free();
    } finally {
        installation.free();
    }
}

// Install a sample application
// installApplication('org.gnome.Calculator').catch(console.error);
// Or install from local file: installFromLocalFile('/path/to/app.flatpakref').catch(console.error);

Example 3: Getting App Data for Store

const { getSystemInstallation } = require("libflatpak");

async function getAppStoreData() {
    const installation = getSystemInstallation();
    if (!installation) {
        throw new Error("No system installation available");
    }

    try {
        // Get all installed applications
        const installedRefs = installation.listInstalledRefs();

        const appData = [];

        for (const ref of installedRefs) {
            // Only process applications (not runtimes)
            if (ref.getKind() === 0) {
                // FLATPAK_REF_KIND_APP
                const appInfo = {
                    id: ref.getName(),
                    name: ref.getAppdataName() || ref.getName(),
                    summary: ref.getAppdataSummary() || "",
                    version: ref.getAppdataVersion() || "Unknown",
                    license: ref.getAppdataLicense() || "",
                    installSize: ref.getInstalledSize(),
                    isCurrent: ref.getIsCurrent(),
                    origin: ref.getOrigin(),
                };

                // Try to load full appdata (may fail if not available)
                try {
                    const appdataBytes = ref.loadAppdata(null);
                    if (appdataBytes && appdataBytes.length > 0) {
                        appInfo.hasFullAppdata = true;
                        // appdataBytes is a Buffer containing the appdata XML
                        // You could parse it with an XML parser for more details
                    }
                } catch (err) {
                    // Appdata not available or failed to load
                    appInfo.hasFullAppdata = false;
                }

                appData.push(appInfo);

                console.log(
                    `${appInfo.name} v${appInfo.version}: ${appInfo.summary}`,
                );
            }
        }

        console.log(`\nTotal applications: ${appData.length}`);
        return appData;
    } finally {
        installation.free();
    }
}

// Also get available applications from remotes
async function getAvailableAppsFromRemote(remoteName) {
    const installation = getSystemInstallation();
    if (!installation) {
        throw new Error("No system installation available");
    }

    try {
        // List remote refs (available applications)
        const remoteRefs = installation.listRemoteRefsSync(remoteName, null);

        console.log(`Available applications in ${remoteName}:`);
        remoteRefs.forEach((ref) => {
            if (ref.getKind() === 0) {
                // FLATPAK_REF_KIND_APP
                console.log(
                    `- ${ref.getName()} (${ref.getDownloadSize()} bytes download)`,
                );
            }
        });

        return remoteRefs;
    } finally {
        installation.free();
    }
}

// Usage
getAppStoreData()
    .then((apps) => {
        console.log(`Found ${apps.length} installed applications`);
    })
    .catch(console.error);

// Uncomment to also check remote applications
// getAvailableAppsFromRemote('flathub').catch(console.error);

API Reference

Top-level Functions

| Function | Description | | ----------------------------------------------- | -------------------------------------------- | | getDefaultArch(): string | Default system architecture (e.g., "x86_64") | | getSupportedArches(): string[] | Array of supported architectures | | getSystemInstallations(): Installation[] | All available system installations | | getSystemInstallation(): Installation \| null | First system installation, if any | | errorQuark(): number | Flatpak error domain quark | | portalErrorQuark(): number | Flatpak portal error domain quark | | parse(ref: string): Ref | Parse a Flatpak ref string | | toString(kind: number): string | Convert operation type to string | | getAll(): Instance[] | Get all running Flatpak instances |

Core Classes

Installation

Represents a Flatpak installation (system or user).

Key Methods:

  • getId(): string - Installation identifier
  • getPath(): string - Filesystem path
  • getIsUser(): boolean - True for user installations
  • listInstalledRefs(cancellable?): InstalledRef[] - List installed applications
  • listRemotes(cancellable?): Remote[] - List configured remotes
  • addRemote(remote, if_needed, cancellable?): boolean - Add a remote
  • getRemoteByName(name, cancellable?): Remote - Get remote by name
  • updateRemoteSync(name, cancellable?): boolean - Update remote metadata

Remote

Represents a remote repository.

Key Methods:

  • getName(): string - Remote name
  • getUrl(): string - Repository URL
  • setUrl(url): void - Set repository URL
  • setGpgVerify(verify): void - Enable/disable GPG verification
  • setTitle(title): void - Set human-readable title
  • setDisabled(disabled): void - Enable/disable remote

Transaction

Manages installation/removal operations.

Key Methods:

  • addInstallFlatpakref(flatpakref_data): boolean - Install from .flatpakref
  • addInstallBundle(file, gpg_data, cancellable?): boolean - Install from bundle
  • addUninstall(ref, cancellable?): boolean - Uninstall application
  • run(cancellable?): boolean - Execute transaction
  • setNoInteraction(no_interaction): void - Disable user interaction
  • setAutoInstallSdk(auto_install_sdk): void - Auto-install SDK

InstalledRef

Represents an installed application or runtime.

Key Methods:

  • getName(): string - Application ID
  • getKind(): number - Ref kind (app/runtime)
  • getAppdataName(): string - Application name from appdata
  • getAppdataSummary(): string - Short description
  • getAppdataVersion(): string - Version string
  • getAppdataLicense(): string - License information
  • loadAppdata(cancellable?): Buffer - Load full appdata XML
  • getInstalledSize(): number - Installation size in bytes

Ref (base class for InstalledRef, RemoteRef, BundleRef)

Base class for all reference types.

TransactionOperation

Individual operation within a transaction.

TransactionProgress

Progress information for transactions.

Instance

Running Flatpak instance.

RelatedRef

Related reference (dependencies).

Memory Management

Native objects are automatically garbage collected, but you can explicitly free them:

const installation = getSystemInstallation();
// ... use installation ...
installation.free(); // Explicit cleanup

Or rely on automatic cleanup when objects go out of scope.

Building from Source

# Clone the repository
git clone https://github.com/yourusername/libflatpak-js.git
cd libflatpak-js

# Install dependencies
npm install

# Generate bindings and build
npm run build

# Run tests
npm test

# Generate fresh bindings from GIR
python3 generate_from_gir.py

Development Dependencies

  • node-addon-api: C++ bindings to Node.js
  • node-gyp: Native module build system
  • pkg-config: Locates libflatpak headers/libraries
  • Python 3: For binding generator

Troubleshooting

Missing Flatpak Development Libraries

Fedora/RHEL:

sudo dnf install flatpak-devel

Debian/Ubuntu:

sudo apt install libflatpak-dev

Arch Linux:

sudo pacman -S flatpak

Build Errors

If you encounter build errors:

  1. Ensure pkg-config can find libflatpak: pkg-config --cflags --libs flatpak
  2. Check Node.js version compatibility (requires Node.js 14+)
  3. Rebuild native module: npm rebuild

Permission Errors

System installations require appropriate permissions. Consider:

  • Using user installations (~/.local/share/flatpak)
  • Running with appropriate privileges
  • Checking Polkit/Flatpak portal permissions

Roadmap

  • [ ] Promise-based async API
  • [ ] TypeScript definitions
  • [ ] Enhanced error reporting
  • [ ] Streaming progress updates
  • [ ] Bundle creation support
  • [ ] Sandbox inspection tools
  • [ ] Portal integration helpers

libflatpak-js is not officially affiliated with the Flatpak project.