FAQ: Why are there two different codebases for TypeScript and Python? This has to do with our history! At first, the project was built in pure python with curses, a python binding for ncurses in C commonly used for UNIX terminal UI apps. However, as the project grew, we found that developing with Typescript gave us several advantages such as React-based UI with Ink (better DX and modern outlook), and better API library that supports MQTT protocol.
If you do not have Node.js installed, you can download and install it from the official website. We recommend using Node.js version 20 or above. We recommend using nvm to manage your Node.js versions, see nvm-sh/nvm.
To get started, you need to install the dependencies:
npm ciWe are using lint-staged and husky for pre-commit hooks to ensure code quality for TypeScript. They are setup automatically when you run npm ci. They will run prettier and xo on staged files before each commit.
If linter and formatter is not run automatically, you can run it manually with:
npm run format # only runs prettier
npm run lint-check # you should ALWAYS run this before committing if it's not automaticTo run the CLI in development mode:
npm run devThis will watch for changes in the source files and rebuild the CLI automatically. You will need to restart the CLI manually to see the changes, run it with:
npm run start -- <command>Basically replace instagram-cli with npm run start, for example:
npm run start -- auth login # = instagram-cli auth login
npm run start -- chat --username some_username # = instagram-cli chat --username some_usernameTo avoid exhausting Instagram's API calls during development, you can use the mock system to test your UI changes. This would not work if you are changing API-related code, but for pure UI changes this is very useful.
npm run start:mock -- --chat | --feed | --storySimilarly, you should update the mock data when making changes to relevant client endpoints.
To build for production locally, this will exclude tests and mocks:
npm run buildWe use esbuild for both production and development builds. You can find the configuration in esbuild.config.mjs.
Refer to this document for several utilities that can help with your development.
This will link the instagram-cli executable to your global node_modules, so you can run instagram-cli from anywhere. If you have it installed from NPM, this will override it.
npm linkUnit tests are not required. But if you're adding new commands that render terminal UI (views), please add basic tests to ensure they run without errors in tests. These are run using ava during CI.
- We use pastel for building CLI commands
pastelsupportstsxfor each commands, so you can just render UI directly in there- Read pastel docs for how to group commands, how to use
zod, etc.
- We use ink for building UI
- We use existing
@inkjs/uicomponents for UI such as alert, text input, loading, etc.
We use ink-picture and wax for image rendering and routing. They are developed in-house but are open-source as well. For those issues, you can open issues in their respective repositories.
source/
├── cli.ts # Main CLI entry point (meow)
├── client.ts # Unified Instagram API client (all IG logic)
├── config.ts # YAML-based config management
├── session.ts # Session serialization and management
│
├── commands/ # Each CLI command in its own file
│ ├── auth/ # Subcommands grouped in folders
│ │ ├── login.tsx
│ │ └── logout.tsx
│ ├── chat.tsx
│ ├── config.tsx
│ ├── notify.tsx
│ ├── stats.tsx
│ └── ...
│
├── ui/
│ ├── components/ # Stateless, reusable Ink components (MessageList, InputBox, etc.)
│ ├── views/ # Top-level stateful views (ChatView, ThreadListView, etc.)
│ ├── hooks/ # Custom React hooks (useClient, useThreads, etc.)
│ └── context/ # React context providers (ClientContext)
│
└── types/ # All TypeScript type definitions
├── instagram.ts
└── ui.ts
You need to cd into the instagram-py directory for Python client development:
cd instagram-pyWe have migrated to uv for managing Python versions and virtual environments. Refer to astral-sh/uv for installation instructions. The simplest way is to install using pip install uv but you may prefer other installation methods.
Create a virtual environment to isolate your dependencies:
uv venv .venv
uv sync
source .venv/bin/activateThis installs all deps (including dev, you can use --no-dev flag to skip those) and builds the package in editable mode.
You can then run the CLI using:
uv run instagram <command>We have removed automatic pre-commit hooks for Python code. Please run the following commands manually to ensure code quality before committing your changes.
uv ruff check .
uv ruff format .Basics tests are in instagram-py/tests. Run them using:
uv run pytest tests/