Version 0.5.4 Release - Native Dependencies and HTTP Requests
Hachi v0.5.4 improves how core-library and third-party modules interact with native C and C++ libraries.
This release focuses on two connected improvements:
- modules can now declare their own native dependencies
- Hachi now includes a new libcurl-backed HTTP client
The main goal is simple: importing a core module should be enough to use it.
Applications should not need to know which compiler and linker flags a module requires internally.
Native Dependencies at the Module Level
Hachi modules can now declare native dependencies using two new actions:
nativePackage: "libcurl"
and:
nativeLink: "curl"
nativePackage resolves the required compiler and linker flags through pkg-config.
For example:
nativePackage: "libcurl"
is resolved internally using the equivalent of:
pkg-config --cflags --libs libcurl
nativeLink provides a simpler direct-linking option:
nativeLink: "curl"
which adds the equivalent of:
-lcurl
These declarations are placed directly inside the module that requires the dependency.
nativePackage: "libcurl"
outerCPP: "
#include <curl/curl.h>
"
When that module is imported, Hachi automatically collects its native requirements and includes them in the backend compiler command.
No More Repeating Module Build Flags
Previously, a Hachi program using libcurl needed to be run with something like:
hachi program.hachi \
-cf "$(pkg-config --cflags --libs libcurl)" \
-go
That worked, but it exposed an internal implementation detail of the module to every application using it.
With v0.5.4, the module carries that requirement itself.
The same program can now be run normally:
hachi program.hachi -go
Hachi resolves the module’s native packages after transpilation and appends the resulting flags to the generated clang++ command.
User-provided -cf flags remain supported and can still be combined with module-declared dependencies.
Dependency Collection and Deduplication
Native dependencies are collected from the complete imported module tree.
If multiple modules declare:
nativePackage: "libcurl"
Hachi resolves and adds that package once.
The same deduplication applies to direct nativeLink declarations.
This allows modules to declare what they need without coordinating dependency ownership with every other module in the application.
Dependency names are also validated before being passed into the native build process.
If a package cannot be resolved through pkg-config, Hachi reports the problem before attempting to compile the generated program.
New net/requests/http Module
Hachi v0.5.4 also introduces a new HTTP client in the core networking library:
>@ "net/requests/http"
The module is backed by libcurl and uses the new native dependency system internally:
nativePackage: "libcurl"
This means applications can import the module and immediately begin making requests without manually supplying libcurl flags.
>@ "net/requests/http"
response: httpGET:
"https://example.com"
print: response
Run it normally:
hachi main.hachi -go
The module supports:
- GET
- POST
- PUT
- PATCH
- DELETE
- HEAD
- OPTIONS
- custom HTTP methods
- custom request headers
- JSON and form request bodies
- authorization headers
- HTTPS certificate verification
- redirects
- compressed responses
- HTTP/2 negotiation when available
General HTTP Requests
The core request function accepts a method, URL, header string, and request body:
httpRequest:
<method>,
<url>,
<headers>,
<body>
For example:
>@ "net/requests/http"
headers: "Content-Type: application/json
Accept: application/json"
body: "{
\"language\": \"Hachi\",
\"working\": true
}"
response: httpRequest:
"POST",
"https://httpbingo.org/anything",
headers,
body
print: response
Custom methods are supported through the same interface:
response: httpRequest:
"PROPFIND",
"https://httpbingo.org/anything/resource",
"Content-Type: text/plain",
"Hachi custom request body"
Responses are currently returned as Hachi strings containing the response headers followed by the response body.
Convenience Request Functions
The module also provides convenience functions for common request types:
httpGET: url
httpPOST: url, body
httpPUT: url, body
httpPATCH: url, body
httpDELETE: url
httpHEAD: url
httpOPTIONS: url
The general httpRequest function remains available when custom headers, authorization, request bodies, or less common methods are required.
Verified End-to-End
The new HTTP module and native dependency pipeline were tested together across:
- query parameters
- custom headers
- JSON POST requests
- form-encoded POST requests
- PUT and PATCH requests
- DELETE requests with and without bodies
- HEAD and OPTIONS requests
- bearer authorization
- arbitrary custom methods
The generated backend command correctly included the flags resolved from libcurl:
clang++ \
'tmp_hc_transpiled.cpp' \
-o 'tmp_hc_compiled' \
-I/usr/include/x86_64-linux-gnu \
-lcurl
No manual -cf option was required.
A Foundation for Native Modules
The HTTP client is the first core module to use this system, but the feature is not specific to networking or libcurl.
Future Hachi modules can use the same mechanism for dependencies such as:
nativePackage: "sqlite3"
nativePackage: "openssl"
or:
nativeLink: "dl"
This gives native-backed modules a cleaner and more self-contained structure.
A module can now declare:
- the Hachi interface it exposes
- the embedded C++ implementation it uses
- the native packages required to compile it
The application only needs to import the module.
Versioning Note
This release is versioned as v0.5.4 because it builds directly on the stability and standard-library work introduced in v0.5.
The language syntax has not undergone a major change, but the compiler and module system are now better equipped to support native-backed core libraries without leaking their build requirements into every application.
This is a relatively focused update, but it opens the door for significantly more capable Hachi modules going forward.
-Mike