Packages for building an application, two frameworks built on them, and forks carrying fixes upstream has not released. Each one stands alone.
yarn add @ecosy/coreimport { Route, NotFound } from "@ecosy/next";
export const GET = Route({ users: Users })
.get(async (ctx) => {
const user = await ctx.users.byId(ctx.params.id);
if (!user) throw new NotFound("No such user");
return user;
});Seventeen packages, each solving one problem and installable on its own. Most carry no dependencies at all; the ones that do depend on another package here, and say so on their own page. Nothing pulls in a framework you did not ask for.
A function returns a class, not an instance. Configuration is a chain, and the chain has no terminal — a half-configured chain and a finished token are the same thing, so it drops straight into an injector.
export const Vendor = Pack(EsmAdapter)
.mount("/services/vendor")
.fetch(HttpFetcher)
.cache(DiskCache(".cache"));
// Vendor is a class. Nothing to call, nothing to await.
export const { GET } = Route({ vendor: Vendor }).get(async (ctx) => {
return ctx.vendor.resolve(ctx.params.path);
});Cacher, Fetcher, Searcher, Hook and Coordinator are structural interfaces with two or three methods. An application that already owns a cache or an HTTP client satisfies them without importing anything from here — which is what keeps the packages free of each other.