Your codebase is a graph.
Stop reading it like a pile of files.

Aracne scans your source tree into a topology — every package, file, function, method, type and interface, plus the edges between them — and hands coding agents an enhanced queryable graph instead of a directory to grep through. All in your machine.

  • Up to30%less context tokens
  • Up to41%less turns
Supports
  • Go
  • Python
  • JavaScript
  • TypeScript
  • Rust
  • Java

How it works

Pick a node. That's a tool call.

Aracne records how your code is wired — a class that inherits, a function that calls a method, a module that imports another — as typed edges an agent can walk and search on. Below is a real arac scan of a small three-module Python project; click any node to see what the read tool hands back.

Click any node · 9 of the 18 nodes this scan found — every one comes back enriched

arac read

      

Every tag on those edges is a type Aracne really stores — calls, inherits, uses_class, imports_module, has_class, has_function, methods. Note that process_order resolves to StripeGateway.charge: the graph already knows which implementation is wired up, which is the question grep cannot answer.

Save tokens with descriptions

A description is what lets the graph answer a question without opening the file it came from. Same task, same agent, both ways — the only difference is whether it can ask for a symbol instead of a filename.

What you need What you pay for anyway

Without Aracne

Two whole files to answer one question

  1. Read orders.py34 lines · 11 useful
    import jsonimport loggingfrom datetime import datetimefrom typing import Optional from money import Moneyfrom payments import StripeGateway logger = logging.getLogger(__name__)  class Order:    """A customer order and the line-item prices it contains."""     def __init__(self, prices: list, note: Optional[str] = None):        """Create an order from a list of line-item prices."""        self.prices = prices        self.note = note     def to_json(self) -> str:        """Serialise the order for the audit log."""        logger.debug("serialising order")        return json.dumps({"prices": self.prices, "note": self.note})     def total(self) -> Money:        """Sum the line items into a single Money total."""        return Money(sum(self.prices))  def process_order(order: Order, api_key: str, placed_at: datetime) -> str:    """Charge an order and return a transaction id stamped with the order time."""    gateway = StripeGateway(api_key)    txn = gateway.charge(order.total())    return f"{txn}@{placed_at.isoformat()}"
  2. Needs yet another full file read

    Read payments.py40 lines · 16 useful
    import hashlibimport loggingfrom abc import ABC, abstractmethod from money import Money logger = logging.getLogger(__name__)  class PaymentError(Exception):    """Raised when a gateway refuses to take the money."""  class PaymentGateway(ABC):    """Contract every payment backend must satisfy."""     @abstractmethod    def charge(self, money: Money) -> str:        """Charge the customer and return the provider's transaction id."""        ...  class StripeGateway(PaymentGateway):    """PaymentGateway backed by the Stripe API."""     def __init__(self, api_key: str):        """Store the Stripe secret key used to sign requests."""        self.api_key = api_key     def _signature(self, cents: int) -> str:        """Sign the request body with the account's secret key."""        return hashlib.sha256(f"{self.api_key}{cents}".encode()).hexdigest()     def charge(self, money: Money) -> str:        """Charge the card via Stripe and return the transaction id."""        cents = money.to_cents()        if cents <= 0:            raise PaymentError("charge amount must be positive")        logger.info("charging %s cents", cents)        return f"ch_{self._signature(cents)[:12]}"

74 lines in context · 47 of them noise

With Aracne

One call, and the follow-up never happens

  1. arac read orders.process_order15 lines · 15 useful
    ```orders.pyimport datetime.datetime def process_order(order: Order, api_key: str, placed_at: datetime) -> str:    """Charge an order and return a transaction id stamped with the order time."""    gateway = StripeGateway(api_key)    txn = gateway.charge(order.total())    return f"{txn}@{placed_at.isoformat()}"``` # CONTEXT:## orders.Order: A customer order and the line-item prices it contains.	orders.Order.total: Sum the line items into a single Money total.## payments.StripeGateway: PaymentGateway backed by the Stripe API.	payments.StripeGateway.charge: Charge the card via Stripe, rejecting any non-positive amount, and return the transaction id.

15 lines in context · nothing wasted

Automatically detect errors

Edits can tell you what you just broke in the the same turn. No need for building or testing.

one batched edit, two filespayments.py · money.py
-    def charge(self, money: Money) -> str:+    def charge(self, money: Money, idempotency_key: str) -> str: -    def to_cents(self) -> int:+    def to_cents(self, rounding: str) -> int:
arac edit — reply, unpromptedno test run, nothing asked
2 edits applied across 2 file(s) Topology warnings (functions that may need manual review):  - [signature_changed] charge changed signature, verify caller orders.process_order (source: payments.StripeGateway.charge, target: orders.process_order)  - [signature_changed] to_cents changed signature, verify caller payments.StripeGateway.charge (source: money.Money.to_cents, target: payments.StripeGateway.charge)

Quickstart

Two steps to a queryable codebase.

1 Install it

Go 1.25+ and a C compiler (the tree-sitter scanners bind through CGO). SQLite is pure Go — nothing else to install. Prefer no toolchain? Take a release binary instead.

go install github.com/Rhuan-Marques/aracne/cmd/arac@latest
arac --version

2 Set it up

One interactive flow. It asks a couple questions and sets up the rest for you

cd /path/to/your/project
arac init

That's it, it's done!

You can quickly generate descriptions using /descriptions-generate in your harness of choice. This uses sub-agents to do the same job as an arac descriptions generate command, uses your credits from your subscription instead of an API key, and shows you the process inside your harness.

You can look at it using:

arac viz serve

You can also try it by hand, the CLI drives the same engine with no LLM in the loop:

arac read internal/topology.TopologyManager internal/topology/domain.Resource
arac grep "incremental scan"
arac warnings list

Every command, flag, MCP tool, hook and config key is in the full documentation →

Where it goes

The graph is the primitive. Now it goes to work.

Next up

Scheduling

Description generation and cleanup are the two jobs that cost tokens and need nobody watching. Scheduling gives them a window — overnight, or any hour you have stepped away — so a repo warms itself and stays tidy on the plan you already pay for, instead of spending your attention and your rate limit in the middle of a session.

In the works

Bug management

A hunter, a judge and a solver: one pass sweeps for defects, a second weighs each one against the topology around it rather than the diff alone, and a third fixes what survives. What is left is running that on a schedule and reporting back — findings you approve, not patches that appear behind you.

In the works

Dead code & graph analytics

A complete call graph can answer reachability, cycles, choke points and the blast radius of a change. An earlier Go-only pass at this shipped and was pulled: the analysis has to work for every language aracne scans, or it is a command that fails for most of the people who try it.

On the horizon

Uniting nodes into functionalities

A feature rarely lives in one function. The plan is to let models group related nodes into a named functionality as they work — and maintain it as the code moves — so that grep and friends can jump straight to "the auth flow" instead of reassembling it from seven files every session. A graph that remembers what its clusters mean.

On the horizon

Aracne’s harness

Every mode so far bends someone else’s harness into topology-shaped answers — a contract to inject, a guard to intercept, a filesystem metaphor to translate. A harness built on the graph from the start has none of that to undo, which is where the topological capabilities stop being a retrofit and start being the interface.

Give your agent the map.

Aracne is open source, self-hosted, and brings no model of its own. Clone it, scan something big, and watch the token counter.