Arc is an AI Architecture Review & Evolution SDK for engineering teams that need repeatable, programmable architecture analysis. It combines provider-backed reasoning with deterministic validation, scoring, dependency analysis, and Mermaid generation behind one strongly typed API.
Use Arc to review a repository before a design review, evaluate a proposed migration, enforce architecture controls in CI, produce audience-specific explanations, or generate machine-readable findings for an internal engineering portal.
npm install @arcinfra/sdk
- Why Arc
- How it works
- Requirements and installation
- Quick start
- Provider configuration
- Architecture review
- Deterministic validation
- Architecture scoring
- Compare, optimize, and explain
- Mermaid diagrams
- Dependency graphs
- Configuration reference
- API reference
- Reliability and error handling
- Security
- Runtime compatibility
- Development
Architecture reviews often become point-in-time documents with inconsistent criteria. Arc makes the review process composable and automatable:
| Capability | What Arc Provides | Provider Call |
|---|---|---|
| Architecture review | Structured findings, recommendations, migration plan, and diagram. | Yes |
| Policy validation | Repeatable checks for operational and design controls. | No |
| Architecture score | Eight normalized scoring dimensions. | No |
| Architecture comparison | Strengths, weaknesses, tradeoffs, recommendation, and risk delta. | Yes |
| Optimization | Cost, deployment, performance, security, and scaling improvements. | Yes |
| Audience explanation | A tailored developer, architect, or executive narrative. | Yes |
| Mermaid generation | Architecture, deployment, sequence, dependency, and service maps. | No |
| Dependency graph | Nodes, typed edges, and circular-dependency detection. | No |
Arc can analyze one source or combine several sources into a richer review.
| Input | Property | Typical Content |
|---|---|---|
| Repository | repository |
Local path containing architecture-relevant files. |
| Architecture narrative | architecture |
Components, relationships, constraints, and data flows. |
| OpenAPI | openapi |
JSON API contract. |
| Terraform | terraform |
Infrastructure definitions. |
| Kubernetes | kubernetes |
Deployments, Services, policies, and autoscaling configuration. |
| Docker Compose | dockerCompose |
Local-development or service topology. |
| Mermaid | mermaid |
Existing architecture diagram source. |
| npm manifest | packageJson |
Serialized package.json content. |
| Business context | context |
Traffic, availability, compliance, cost, and team constraints. |
Arc separates deterministic analysis from provider-backed reasoning. This makes fast policy checks possible without credentials while preserving deeper AI-assisted review when needed.
flowchart LR
subgraph Inputs["Architecture inputs"]
Repo["Repository"]
Specs["OpenAPI / IaC / manifests"]
Narrative["Architecture narrative"]
Context["Operational context"]
end
subgraph ArcSDK["Arc SDK"]
Normalize["Bounded input collection"]
Rules["Deterministic rule engine"]
Graph["Dependency graph + cycle detection"]
Provider["Provider abstraction"]
Schema["Zod response validation"]
Score["Deterministic scoring"]
end
subgraph Outputs["Typed outputs"]
Review["ArchitectureReview"]
Violations["RuleViolation[]"]
Diagrams["Mermaid diagrams"]
Plan["Recommendations + migration plan"]
end
Repo --> Normalize
Specs --> Normalize
Narrative --> Normalize
Context --> Normalize
Normalize --> Rules --> Violations
Normalize --> Graph --> Diagrams
Normalize --> Provider --> Schema --> Review
Review --> Score
Review --> Plan
sequenceDiagram
participant App as Application
participant Arc as Arc SDK
participant Provider as AI provider
participant Zod as Zod validator
App->>Arc: architecture.review(input)
Arc->>Arc: Collect and bound repository context
Arc->>Provider: Sanitized HTTPS request
alt Retryable status or network failure
Provider-->>Arc: 408 / 429 / 5xx
Arc->>Arc: Capped exponential backoff
Arc->>Provider: Retry request
end
Provider-->>Arc: Structured response
Arc->>Zod: Validate complete response
alt Valid response
Zod-->>Arc: ArchitectureReview
Arc-->>App: Typed result
else Invalid response
Zod-->>Arc: Validation issues
Arc-->>App: ValidationError
end
-
Node.js 20 or newer
-
A provider API key for AI-backed operations
-
No credentials for validation, scoring, diagrams, or dependency graphs
npm install @arcinfra/sdk
Arc ships ESM, CommonJS, and TypeScript declarations. Provider requests use the native Node.js fetch implementation.
import "dotenv/config";
import { Arc } from "@arcinfra/sdk";
const arc = new Arc({
provider: "openai",
apiKey: process.env.OPENAI_API_KEY,
});
const review = await arc.architecture.review({
repository: process.cwd(),
context: {
productionTrafficRps: 2_500,
availabilityTarget: "99.95%",
primaryRegion: "ap-southeast-1",
constraints: ["SOC 2", "zero-downtime deployments"],
},
});
console.log(review.summary);
console.table(arc.architecture.score(review));For deterministic checks only:
import {
Arc,
generateDependencyGraph,
type AIProvider,
validateArchitecture,
} from "@arcinfra/sdk";
// A provider is required when constructing an Arc client.
// Deterministic utilities can be imported and used directly without one.
const violations = validateArchitecture({
architecture: "gateway -> orders\norders -> postgres",
});
const graph = generateDependencyGraph({
architecture: "gateway -> orders\norders -> postgres",
});OpenAI is the default provider. Set a provider explicitly when using xAI, Gemini, or Claude.
| Provider | Identifier | Default Model | API Key Variable | Model Variable | |
|---|---|---|---|---|---|
| OpenAI | openai |
gpt-5-mini |
OPENAI_API_KEY |
OPENAI_MODEL |
|
| xAI | xai |
grok-4 |
XAI_API_KEY |
XAI_MODEL |
|
| Google Gemini | gemini |
gemini-2.5-pro |
GEMINI_API_KEY |
GEMINI_MODEL |
|
| Anthropic Claude | claude |
claude-sonnet-4 |
ANTHROPIC_API_KEY |
CLAUDE_MODEL |
_ |
const arc = new Arc({
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
model: process.env.OPENAI_MODEL,
});const arc = new Arc({
provider: 'xai',
apiKey: process.env.XAI_API_KEY,
model: process.env.XAI_MODEL,
});const arc = new Arc({
provider: 'gemini',
apiKey: process.env.GEMINI_API_KEY,
model: process.env.GEMINI_MODEL,
});const arc = new Arc({
provider: 'claude',
apiKey: process.env.ANTHROPIC_API_KEY,
model: process.env.CLAUDE_MODEL,
});OPENAI_API_KEY=
OPENAI_MODEL=gpt-5-mini
XAI_API_KEY=
XAI_MODEL=grok-4
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.5-pro
ANTHROPIC_API_KEY=
CLAUDE_MODEL=claude-sonnet-4
ARC_BASE_URL=
Arc includes dotenv for applications that want it, but does not implicitly mutate the process environment. Import dotenv/config or call config() in your application.
Implement AIProvider to connect an internal model gateway, self-hosted model, test double, or unsupported provider.
import {
Arc,
type AIProvider,
type ArchitectureComparison,
type ArchitectureReview,
type CompareInput,
type ExplainInput,
type OptimizationResult,
type ReviewArchitectureInput,
} from "@arcinfra/sdk";
class InternalProvider implements AIProvider {
readonly name = "internal-gateway";
readonly model = "architecture-review-v3";
async reviewArchitecture(
input: ReviewArchitectureInput,
): Promise<ArchitectureReview> {
return callInternalGateway("review", input);
}
async optimizeArchitecture(input: {
review: ArchitectureReview;
signal?: AbortSignal;
}): Promise<OptimizationResult> {
return callInternalGateway("optimize", input);
}
async compareArchitectures(
input: CompareInput,
): Promise<ArchitectureComparison> {
return callInternalGateway("compare", input);
}
async explainArchitecture(input: ExplainInput): Promise<string> {
return callInternalGateway("explain", input);
}
}
const arc = new Arc({
provider: new InternalProvider(),
});Custom providers own their transport and response-validation behavior. Built-in providers validate AI results with Arc's exported Zod schemas.
architecture.review() accepts multiple sources and returns a complete ArchitectureReview.
const review = await arc.architecture.review({
architecture: `
edge -> api
api -> orders
orders -> postgres
orders -> events
`,
openapi: JSON.stringify(openApiDocument),
kubernetes: deploymentYaml,
context: {
workload: "transactional",
peakRps: 8_000,
dataResidency: ["EU"],
recoveryPointObjective: "5 minutes",
},
});When repository is supplied, Arc:
-
Resolves the path locally.
-
Traverses no deeper than four directory levels.
-
Excludes hidden directories,
node_modules,dist, andcoverage. -
Collects architecture-relevant manifests, specifications, Markdown, Terraform, and Mermaid files.
-
Caps individual files at 20,000 characters and total collected context at 100,000 characters.
-
Sends the bounded context to the configured provider.
Do not pass an untrusted repository path without validating and constraining it in your application.
interface ArchitectureReview {
summary: string;
score: number; // 0–100
strengths: Finding[];
risks: Finding[];
bottlenecks: Finding[];
security: Finding[];
scalability: Finding[];
reliability: Finding[];
maintainability: Finding[];
recommendations: Recommendation[];
migrationPlan: MigrationStep[];
architectureDiagram: ArchitectureDiagram;
metadata: Metadata;
}Findings use the severity scale info, low, medium, high, and critical. Recommendations contain priority, effort, and expected impact. Migration steps include sequence, risk, and rollback guidance.
Validation does not send data to an AI provider. It is appropriate for CI checks, editor feedback, and pre-review diagnostics.
const violations = arc.architecture.validate({
architecture: architectureText,
openapi: JSON.stringify(openApiDocument),
kubernetes: kubernetesYaml,
});
for (const violation of violations) {
console.log(
`[${violation.severity}] ${violation.rule}: ${violation.message}`,
);
}arc.rules.validate(input) is an alias for the same deterministic engine.
| Rule | Detects |
|---|---|
circular-dependencies |
Package or service dependency cycles. |
missing-ownership |
No owner, ownership model, or CODEOWNERS evidence. |
missing-authentication |
No documented authentication mechanism. |
missing-monitoring |
No monitoring or metrics strategy. |
missing-backups |
No backup or snapshot strategy. |
single-point-of-failure |
No redundancy, replicas, or failover approach. |
weak-scaling-strategy |
No horizontal or automatic scaling strategy. |
missing-retry-policies |
No retry or backoff behavior. |
missing-rate-limiting |
No rate limiting or throttling controls. |
undocumented-apis |
No OpenAPI, Swagger, or API documentation. |
inconsistent-naming |
Component names that differ only by letter case. |
orphan-components |
Components with no documented relationships. |
missing-disaster-recovery |
No disaster-recovery plan, RPO, or RTO. |
missing-observability |
No tracing or distributed observability approach. |
import { readFile } from "node:fs/promises";
import { validateArchitecture } from "@arcinfra/sdk";
const architecture = await readFile("docs/architecture.md", "utf8");
const violations = validateArchitecture({ architecture });
const blocking = violations.filter(
({ severity }) => severity === "high" || severity === "critical",
);
if (blocking.length > 0) {
console.error(JSON.stringify(blocking, null, 2));
process.exitCode = 1;
}Scoring is deterministic and derived from the categorized findings in a validated review.
const score = arc.architecture.score(review);
// {
// overall: 82,
// security: 80,
// performance: 90,
// cost: 78,
// scalability: 85,
// maintainability: 84,
// reliability: 79,
// developerExperience: 82
// }flowchart TB
Review["Validated ArchitectureReview"] --> Categories["Categorized finding penalties"]
Categories --> Security["Security"]
Categories --> Performance["Performance"]
Categories --> Scalability["Scalability"]
Categories --> Reliability["Reliability"]
Categories --> Maintainability["Maintainability"]
Review --> Cost["Cost signals"]
Review --> DX["Developer experience"]
Security --> Overall["Averaged normalized overall score"]
Performance --> Overall
Scalability --> Overall
Reliability --> Overall
Maintainability --> Overall
Cost --> Overall
DX --> Overall
Scores are bounded to the inclusive range 0-100. Use the component scores to prioritize action; avoid treating the overall score as a substitute for engineering judgment.
Both current and proposed accept a complete review or a textual architecture description.
const comparison = await arc.architecture.compare({
current: currentReview,
proposed: proposedReview,
});
console.log(comparison.strengths);
console.log(comparison.weaknesses);
console.log(comparison.tradeoffs);
console.log(comparison.recommendation);
console.log(comparison.riskDelta);const optimization = await arc.architecture.optimize({ review });
console.log(optimization.cheaperAlternatives);
console.log(optimization.easierDeployment);
console.log(optimization.performanceImprovements);
console.log(optimization.securityImprovements);
console.log(optimization.scalingImprovements);const developerGuide = await arc.architecture.explain({
review,
audience: "developer",
});
const architectureBrief = await arc.architecture.explain({
review,
audience: "architect",
});
const executiveSummary = await arc.architecture.explain({
review,
audience: "executive",
});| Audience | Emphasis |
|---|---|
developer |
Implementation impact, interfaces, failure modes, and practical changes. |
architect |
System boundaries, tradeoffs, quality attributes, and evolution path. |
executive |
Business risk, cost, delivery impact, and strategic recommendations. |
Diagram generation is deterministic and does not invoke a provider.
const source = arc.diagrams.generate({
type: "dependency",
architecture: `
gateway -> identity
gateway -> orders
orders -> postgres
orders -> events
`,
});
console.log(source);| Diagram Type | Value | Layout |
|---|---|---|
| Architecture | architecture |
Left-to-right flowchart |
| Deployment | deployment |
Top-to-bottom flowchart |
| Sequence | sequence |
Mermaid sequence diagram |
| Dependency | dependency |
Left-to-right dependency flowchart |
| Service map | service-map |
Left-to-right service flowchart |
Example generated topology:
flowchart LR
gateway["gateway"] -->|depends_on| identity["identity"]
gateway -->|depends_on| orders["orders"]
orders -->|depends_on| postgres["postgres"]
orders -->|depends_on| events["events"]
Arc creates a JSON graph from package.json, OpenAPI, and architecture relationships.
const graph = arc.dependencies.graph({
packageJson: JSON.stringify(packageJson),
openapi: JSON.stringify(openApiDocument),
architecture: "api -> database\ndatabase -> audit",
});
for (const cycle of graph.cycles) {
console.warn(`Cycle: ${cycle.join(" -> ")}`);
}interface DependencyGraph {
nodes: Array<{
id: string;
type: "package" | "service" | "endpoint" | "component";
metadata?: Record<string, unknown>;
}>;
edges: Array<{
from: string;
to: string;
type: "depends_on" | "calls" | "contains";
}>;
cycles: string[][];
}interface ArcConfig {
provider?: "openai" | "xai" | "gemini" | "claude" | AIProvider;
apiKey?: string;
model?: string;
timeoutMs?: number;
maxRetries?: number;
baseUrl?: string;
logger?: Logger;
}| Option | Default | Validation & Behavior |
|---|---|---|
provider |
openai |
Accepts a built-in provider identifier or a custom AIProvider instance. |
apiKey |
Provider environment variable | Required by built-in providers and never written to logs. |
model |
Provider default or model environment variable | Overrides the provider’s default model. |
timeoutMs |
30000 |
Must be greater than 0; applied to every request attempt. |
maxRetries |
2 |
Must be a non-negative integer. |
baseUrl |
Provider API endpoint | May point to an API gateway or compatible proxy. |
logger |
Silent logger | Receives sanitized provider, operation, and attempt metadata. |
Resolution precedence is explicit constructor option, environment variable, then SDK default.
| Method | Input | Return Type | Deterministic |
|---|---|---|---|
arc.architecture.review() |
ReviewArchitectureInput |
Promise<ArchitectureReview> |
No |
arc.architecture.validate() |
ReviewArchitectureInput |
RuleViolation[] |
Yes |
arc.architecture.compare() |
CompareInput |
Promise<ArchitectureComparison> |
No |
arc.architecture.optimize() |
{ review, signal? } |
Promise<OptimizationResult> |
No |
arc.architecture.score() |
ArchitectureReview |
ArchitectureScore |
Yes |
arc.architecture.explain() |
ExplainInput |
Promise<string> |
No |
arc.diagrams.generate() |
Diagram input | string |
Yes |
arc.rules.validate() |
ReviewArchitectureInput |
RuleViolation[] |
Yes |
arc.dependencies.graph() |
Graph input | DependencyGraph |
Yes |
The package also exports the deterministic functions, provider classes, schemas, types, and error classes:
import {
ClaudeProvider,
GeminiProvider,
OpenAIProvider,
XAIProvider,
comparisonSchema,
generateDependencyGraph,
generateDiagram,
optimizationSchema,
reviewSchema,
scoreArchitecture,
validateArchitecture,
} from "@arcinfra/sdk";classDiagram
Error <|-- ArcError
ArcError <|-- ConfigurationError
ArcError <|-- ValidationError
ArcError <|-- ProviderError
ProviderError <|-- AuthenticationError
ProviderError <|-- RateLimitError
ProviderError <|-- TimeoutError
ProviderError <|-- ResponseError
| Error | Meaning |
|---|---|
ConfigurationError |
Missing credentials, invalid timeout or retry settings, or an unsupported configuration. |
ValidationError |
The provider response failed validation against the expected Zod schema. |
ProviderError |
A provider HTTP request or network operation failed. |
AuthenticationError |
The provider returned HTTP 401 or 403. |
RateLimitError |
Rate limiting persisted after all configured retry attempts. |
TimeoutError |
A provider attempt exceeded the configured timeoutMs. |
ResponseError |
The provider returned invalid JSON or an unexpected response shape. |
import {
AuthenticationError,
ProviderError,
RateLimitError,
TimeoutError,
ValidationError,
} from "@arcinfra/sdk";
try {
const review = await arc.architecture.review({ architecture });
} catch (error) {
if (error instanceof ValidationError) {
console.error("Invalid provider response", error.issues);
} else if (error instanceof AuthenticationError) {
console.error("Check the provider credential");
} else if (error instanceof RateLimitError) {
console.error("Retry later or reduce concurrency");
} else if (error instanceof TimeoutError) {
console.error("Increase timeoutMs or inspect provider latency");
} else if (error instanceof ProviderError) {
console.error("Provider request failed", error.status);
}
throw error;
}Arc retries network failures and these HTTP statuses:
| Status | Reason |
|---|---|
408 |
Request timeout |
429 |
Rate limited |
500 |
Internal server error |
502 |
Bad gateway |
503 |
Service unavailable |
504 |
Gateway timeout |
Backoff starts at 250 ms, doubles per retry, and is capped at 2 seconds. Authentication and non-retryable client errors fail immediately.
All provider-backed input types support AbortSignal.
const controller = new AbortController();
const pending = arc.architecture.review({
architecture,
signal: controller.signal,
});
setTimeout(() => {
controller.abort(new Error("Request cancelled"));
}, 5_000);
const review = await pending;Cancellation stops the active fetch request and any pending retry delay.
Arc uses a silent logger by default. A custom logger has debug, info, warn, and error methods:
const arc = new Arc({
apiKey: process.env.OPENAI_API_KEY,
logger: {
debug: (message, meta) => telemetry.debug(message, meta),
info: (message, meta) => telemetry.info(message, meta),
warn: (message, meta) => telemetry.warn(message, meta),
error: (message, meta) => telemetry.error(message, meta),
},
});Built-in providers never send prompts, API keys, authorization headers, or response bodies to the logger.
-
Keep provider keys on trusted servers; never expose them in browser bundles.
-
Scope, rotate, and monitor provider credentials.
-
Redact secrets, personal data, customer data, and proprietary source before external review.
-
Validate repository paths and restrict them to an approved workspace.
-
Apply least-privilege filesystem permissions to the process running Arc.
-
Treat AI recommendations as engineering input, not an automatic deployment authorization.
-
Enforce deterministic rules in CI and require human approval for high-impact changes.
-
Use a controlled
baseUrlonly when routing through a trusted gateway. -
Ensure custom loggers preserve Arc's prompt and credential redaction guarantees.
flowchart LR
Browser["Browser / developer portal"] -->|Authenticated request| Backend["Trusted backend"]
Backend -->|Validated repository reference| Arc["Arc SDK"]
Arc -->|TLS + server-side key| AI["Configured AI provider"]
Arc --> Rules["Deterministic validation"]
Backend --> Store["Access-controlled report store"]
Arc --> Backend
| Environment | Support | Notes |
|---|---|---|
| Node.js 20+ (ESM) | Supported | Import directly from @arcinfra/sdk. |
| Node.js 20+ (CommonJS) | Supported | Load with require("@arcinfra/sdk"). |
| TypeScript strict mode | Supported | Complete declaration files are included. |
| Serverless Node runtimes | Supported | Set provider timeouts within your platform’s execution limit. |
| Browser | Not supported | Repository review relies on Node.js filesystem APIs. Run Arc from a trusted backend. |
| Edge runtimes | Not guaranteed | The main client depends on Node.js filesystem APIs. |
ESM:
import { Arc } from '@arcinfra/sdk';CommonJS:
const { Arc } = require('@arcinfra/sdk');
src/
├── architecture/ Review types, comparisons, optimization, explanations, scoring
├── client/ Arc client and configuration resolution
├── dependency/ Dependency graph generation and cycle detection
├── diagrams/ Deterministic Mermaid diagram generation
├── errors/ Typed SDK error hierarchy
├── logging/ Logger contract and silent default implementation
├── providers/ Provider interface and built-in transports
├── rules/ Deterministic architecture validation engine
├── schemas/ Zod schemas for validated responses
├── types/ Public TypeScript contracts
└── index.ts Package entry point and public exports
tests/ Unit tests and mocked provider tests
examples/ Provider integrations and end-to-end workflow examples
npm install
npm run typecheck
npm run lint
npm test
npm run build
npm pack --dry-run
| Command | Purpose |
|---|---|
npm run typecheck |
Validate the codebase with strict TypeScript checks—without generating output files. |
npm run lint |
Run ESLint across the SDK source, test suite, and examples. |
npm test |
Execute the complete Vitest suite once. |
npm run test:watch |
Keep Vitest running and re-run relevant tests as files change. |
npm run build |
Produce ESM, CommonJS, source maps, and TypeScript declarations with tsup. |
npm pack --dry-run |
Preview exactly which files would be included in the published npm package. |
The default suite uses mocked provider responses and does not require real API keys. Real-provider integration tests should be opt-in and isolated from normal CI.
Read CONTRIBUTING.md before submitting a change. Contributions should include focused tests, preserve public type safety, and pass the complete release gate.
MIT. See LICENSE.