
r/Deno

Optique 1.1.0: Command discovery, value parsers, and ordered grammars
github.comI built a code-first build system for Deno/TypeScript because I got tired of YAML — would love some eyes on it
So this started as a personal itch. I kept writing build/CI logic in YAML and shell scripts and hating that none of it was typed, refactorable, or debuggable. If I renamed a step, nothing told me what broke. So I built Zuke — a build system where you define targets as TypeScript class fields and wire dependencies with real references instead of magic strings.
The core idea: a target references another with this.compile, not "compile". Rename it and the compiler updates every reference. Zuke resolves the dependency graph and runs everything in topological order, exactly once. It's all just async TypeScript functions, so you get full editor support, types, and an actual debugger.
A few things I'm happy with:
- Generates GitHub Actions / GitLab / Azure YAML from code, and checks it's up to date on each run
- A
$tagged-template shell that escapes interpolations so you don't footgun yourself with injection - Typed wrappers for a bunch of common tools (Deno, Docker, kubectl, Vite, etc.)
- Zero runtime deps — it runs on Deno and bootstraps Deno for you on first run
It's v1 and I'm sure there are rough edges, which is exactly why I'm posting. I'd really like people to actually try it on a real project and tell me where it annoys them or breaks. Honest "this is worse than X because Y" feedback is the most useful thing right now.
Repo and docs: https://zuke.build (MIT licensed)
Inspired heavily by NUKE from the .NET world, if that lineage means anything to you.
A week ago I posted about ArchUnitTS, my library for enforcing architecture rules in TypeScript projects as unit tests.
A few of you specifically asked whether this could be used to enforce clean Angular feature/module boundaries in real projects:
making sure feature modules don’t import directly from each other’s internal files, and instead communicate through public API barrel files like index.ts or public-api.ts.
So to that request I’ve added exactly that.
First a mini recap of what ArchUnitTS does:
- Most tools catch style issues, formatting issues, or generic smells.
- ArchUnitTS focuses on structural rules: wrong dependency directions, circular dependencies, naming convention drift, architecture/diagram mismatch, code metrics, and so on.
- You define those rules as tests, run them in Jest/Vitest/Jasmine/Mocha/etc., and they automatically become part of CI/CD.
In other words: ArchUnitTS allows you to enforce your architectural decisions by writing them as simple unit tests.
That matters more than ever in Claude Code / Codex times, because LLMs are great at generating code but they love to violate architectural boundaries, especially when they get stuck.
Repo: https://github.com/LukasNiessen/ArchUnitTS
Now what’s new
Exclusion-aware dependency rules for Angular public API boundaries
Before, ArchUnitTS could already enforce internal dependency rules like:
- “components must not depend on infrastructure”
- “core must not depend on shared”
- “feature A must not depend on feature B”
- “folders must be cycle-free”
But one common Angular case was still a bit annoying to express cleanly:
A component in one feature should not import directly from another feature’s internal files.
For example, this should usually be forbidden:
import { OrderService } from '../orders/internal/order.service';
import { OrderCardComponent } from '../orders/components/order-card.component';
But this should be allowed:
import { OrderSummary } from '../orders';
import { PUBLIC_ORDERS_TOKEN } from '../orders/public-api';
This is not technically always a circular dependency.
But it is still architectural coupling.
It means another feature now knows the internal folder structure of orders. If the orders feature reorganizes its components, services, hooks, facades, or models, unrelated features can suddenly break.
So ArchUnitTS now supports except in pattern matchers.
Example:
import { projectFiles } from 'archunit';
it('should consume orders only through its public API', async () => {
const rule = projectFiles()
.inPath('src/app/**/*.ts', {
except: { inPath: 'src/app/orders/**' },
})
.shouldNot()
.dependOnFiles()
.inFolder('src/app/orders/**', {
except: ['index.ts', 'public-api.ts'],
});
await expect(rule).toPassAsync();
});
This says:
- check all Angular app files
- exclude files inside
ordersitself, because a module may use its own internals - forbid other features from depending on files inside
orders - but allow imports through
orders/index.tsandorders/public-api.ts
So this fails:
import { OrderService } from '../orders/internal/order.service';
But this passes:
import { OrderSummary } from '../orders';
You can also make the exceptions explicit by target:
.inFolder('src/app/orders/**', {
except: {
withName: ['index.ts', 'public-api.ts'],
},
});
This is especially useful in Angular projects because Angular feature modules often create natural architectural boundaries, but violations tend to accumulate silently over time.
And these imports are very hard to catch in code review because they look like normal TypeScript imports.
Now the boundary can be tested directly.
Very curious for any type of feedback! PRs are also highly welcome.