Repository navigation
Releases: open-southeners/lambdary
Releases · open-southeners/lambdary
Release list
1.1.0
Added
- Lambda layers: a
layers:manifest key accepting layer version ARNs
and local directories/.zipfiles — up to 5 per function, merged in
order into/optexactly like AWS (later entries win). ARNs are fetched
using your own AWS credentials (works for public third-party layers such
as Bref's), cached under.lambdary/, and digest-pinned in
.lambdary/lock. Bref-style custom runtimes (provided.*) can now get
theirbootstrapfrom a layer instead of needing a localbootstrap
file. On the process backend, pure-code layers resolve through the
runtimes' own standard search paths (NODE_PATH,PYTHONPATH,
RUBYLIB/GEM_PATH,PATH); a function whose layer content must run on
Amazon Linux falls back to the container backend automatically, with a
notice. - Response streaming (
url.invoke_mode: RESPONSE_STREAM): a function
wrapped inawslambda.streamifyResponsenow gets its real HTTP status
code, headers, and cookies back on its local route, instead of the raw
http-integration-responseframe — JSON prelude, NUL-byte delimiter, and
all — leaking straight through as the body. This is a correctness fix as
much as a new capability: anyone already testing a streaming handler
locally was silently getting that wrong response with no diagnostic. The
response is still fully buffered by the emulator end to end, so this
doesn't add time-to-first-byte streaming locally — only a correct
one-shot response.
1.0.1
Changed
- Release binaries now build with Go 1.26.6, closing out every stdlib
vulnerability flagged against the previous toolchain (net/http,
crypto/tls,net/url,crypto/x509, and others).
Fixed
- HTTP responses with a body-less status (
204 No Content,304 Not Modified,1xx) no longer fail with "response status code does not
allow body" now that the Go 1.26 standard library enforces that rule
strictly.
1.0.0
Added
- An
examples/playground with three ready-to-run functions: a Node.js
Playwright screenshot service (GET /screenshot?url=...), a Python
image-thumbnail service (POST /thumbnail), and a Go checksum service
with its ownDockerfile(POST /checksum) — together covering binary
request/response bodies, query strings, environment config, and
Dockerfile-based container functions end to end. - Prebuilt
lambdarybinaries for Linux and macOS (amd64 + arm64) are now
attached to every GitHub release, with SHA-256 checksums, and release
notes are generated automatically from this changelog. - Release binaries now bundle AWS's Lambda Runtime Interface Emulator, so
the process backend works out of the box with nogit/gorequired
(source builds viago installkeep the build-from-source fallback). - Function discovery: every direct subdirectory of the project root that
contains a.lambda.ymlor a recognizable project file (package.json,
composer.json,pyproject.toml/requirements.txt,go.mod,Gemfile,
*.csproj,Dockerfile) is picked up as a Lambda function, with its
runtime inferred from that marker; a.lambda.ymlcan always override the
inferred runtime. .lambda.ymlmanifest: per-function configuration that mirrors AWS
Lambda's own vocabulary (runtime,handler,timeout,memory,
architectures,environment,url) plus a local-onlylocalsection
(backend,image,command,env_file) for how the function runs on
your machine. A project-widelambdary.ymlcan setport, the functions
root, anddefaultsinherited by every function manifest. Unknown keys
in either file are rejected so typos surface immediately instead of being
silently ignored.lambdary listcommand: prints every discovered function with its
runtime, backend, and local route. Misconfigurations — route collisions,
duplicate function names, unresolvable runtimes, invalid manifests — are
reported as warnings alongside the table rather than aborting the listing,
so a problem in one function never hides the rest.- macOS groundwork: confirmed AWS's own Lambda Runtime Interface Emulator
(pinned upstream tagv1.35) builds and runs natively on Apple Silicon, so
local (non-container) function execution will run on AWS's real emulator
instead of a reimplementation. lambdary dev: runs every discovered function behind one local HTTP
server, with an AWS-compatible invoke endpoint
(POST /2015-03-31/functions/<name>/invocations) that works unchanged
withaws lambda invoke --endpoint-url. Functions start on their first
invocation by default;--eagerstarts them all up front instead.
Ctrl-C (or SIGTERM) shuts the server down gracefully and stops every
running function before exiting.lambdary invoke <function>: invokes a function once and prints its
response. It sends the request to an already-runninglambdary dev
server when one is listening on--port, or otherwise starts the
function just for that one call and stops it again afterwards. The
event body comes from-e <file>,-e -(stdin), or defaults to{}.- Functions run as containers on AWS's own Lambda base images: each gets
its own container with its code bind-mounted in, starts on demand, and
is torn down cleanly on shutdown — no manual cleanup needed even after a
crash, since containers are labelled and discoverable
(docker ps --filter label=lambdary). - Fail-safe collision handling at runtime: if two functions share a name or
route,lambdarystill starts and serves every other function normally;
hitting the colliding function or route returns a409response naming
every function competing for it. - Functions are now reachable as plain HTTP endpoints at their local route
(e.g.GET /hello), not just through the invoke passthrough: a request
arrives at the handler as an AWS Function URL / API Gateway v2 (2.0)
event, with headers, cookies, query strings, and binary bodies mapped in
both directions. Handlers can return either a plain value (serialized as
the JSON body,200) or a shaped response (statusCode,headers,
cookies,isBase64Encoded) for full control over the HTTP reply. - Process backend: run functions without Docker, using
--backend process(or the default--backend auto, which now falls back to it
automatically — with a clear notice — when no container runtime is
usable). Functions are driven by AWS's own Lambda Runtime Interface
Emulator against your host's own Node, Python, or custom (bootstrap)
runtime instead of a container; the emulator is built from pinned
upstream source and cached on first use (a one-time ~30s build). Node and
Python functions run through small built-in shims with no extra
dependencies;local.commandin.lambda.ymlstill overrides the
spawned command entirely. Since there's no container image involved, the
process backend runs on whatever runtime versions are installed on your
machine rather than AWS's pinned Lambda runtime — closer to your host,
not a perfect match for AWS's environment. - Hot reload, on by default in
lambdary dev: editing a function's code
restarts just that function, cold-starting it fresh on its next request.
Adding or removing a function directory, or editing a.lambda.ymlor the
project'slambdary.yml, reconfigures the whole server on the fly —
re-discovering every function and swapping in the new set without
dropping the listener. A broken edit is logged with what went wrong and
the previous, working configuration keeps running rather than taking the
server down. Disable with--no-reload. - Live function logs: each function's combined stdout/stderr — including
the emulator's Lambda-styleREPORTlines — streams tolambdary dev's
own output as soon as an instance starts, prefixed[<name>]in a color
cycled per function. Color is skipped automatically when output isn't a
terminal, and always whenNO_COLORis set. lambdary init <name>: scaffolds a new function directory with a
ready-to-run handler and.lambda.yml, so starting a function needs no
boilerplate.--runtimepicks the stub (nodejs22.xby default,
python3.13, orprovided.al2023— a working Runtime APIbootstrap
echo loop, not just a placeholder). Refuses to overwrite an existing
directory.- API Gateway REST API (
1.0) payload format, selectable per function
viaurl.payload: "1.0"instead of the default"2.0"— events carry
the REST API shape (resource,pathParameters.proxy,
multiValueHeaders, …) and, like the real service, the response
contract is strict: a handler must return a shaped{statusCode, ...}
object. Dockerfilefunctions: a function directory with aDockerfileand
noruntime/local.imagenow builds and runs automatically — no more
manualdocker build. It rebuilds on every start, so hot reload picks up
Dockerfileand code edits the same way any other function does..lambdary/lock: the container backend records each function's
resolved image digest the first time it starts and pins subsequent
starts to that digest. Commit the file for reproducible starts across
machines; a locally builtDockerfileimage or an explicit
local.imageoverride is never pinned.local.env_file: loads extra environment variables for a function
from a dotenv-style file (KEY=VALUEper line,#comments, optional
exportprefix), merged under the manifest's ownenvironmentblock —
explicitenvironmentkeys always win on conflict.- Ruby on the process backend:
ruby*functions now run natively
through a dependency-free embedded shim, the same as Node and Python,
including AWS's own Ruby handler notation — class/module handlers like
file.Class.method, not just a top-level function. - Automatic container fallback for the process backend: a function
whose runtime has no process-backend shim (Java, .NET, …) now runs in a
container automatically, with a one-line notice, instead of failing the
invoke; it only errors when no container runtime is available either.
Fixed
- The process backend's Node runtime no longer crashes after ~5 minutes
idle between invocations — routine for a local dev server, but fatal
for its Runtime API long-poll, which used to run overfetch()and hit
undici's default 5-minute header timeout. Every invocation after that
crash used to fail untildevwas restarted. - A function's own
.lambda.ymllocal: backendsetting is now honored:
previouslydev/invokepicked one backend for every function, so a
function declaringlocal.backend: process(to dodge a container-image
limitation, for example) silently ran on the container backend anyway
whenever Docker was available. Different functions can now genuinely run
on different backends within the samelambdary devserver. - A crashed function runtime is now replaced on the next invocation instead
of failing forever: an invoke that finds its instance dead — a
Runtime.ExitErrorresponse, or a connection failure, the latter
retried once transparently — evicts that instance so the next invoke
cold-starts a fresh one, matching real Lambda's replace-on-crash
behavior. provided.*functions now run on the container backend without a
Dockerfile: the function'sbootstrapfile is mounted where the AWS
base image's entrypoint expects it. Compiled custom runtimes still need
their binary built beforehand — that remains a known limitation.