Hypertext Functions (HTFN) CLI (Alpha). To view our terms of service, please run: htfn terms
Create JavaScript (or TypeScript) functions that run in the cloud. Start building APIs,
websites and single page applications in just a few key presses.
Build hypertext functions like this in seconds:
``js
// myfunc.ts
export default function (req: Request) {
return Response.json({ message: "Hellorld!", url: req.url });
}
`
Deploy the function immediately, no build step required: š
`bash`
htfn deploy myfunc ./myfunc.ts
š„ Drumroll please... https://myfunc-7klq1kn1srxlcmhm.fn.htfn.io
---
> Hypertext functions do not run inside NodeJS, they use Google V8 directly,
> so functions cannot call any of the NodeJS APIs. This here is WinterCG country š¦
Not all WinterCG runtime APIs are implemented (yet), but this is work in progress. At the moment, you can use the following:
- fetch()console.*
- localStorage.*
- self.crypto.randomUUID()
- self.crypto.getRandomValues()
- setTimeout()
- setInterval()
- btoa()
- atob()
- TextDecoder
- TextEncoder
-
Please note that all assets (css, images, JavaScript bundles, etc.) are aggressively HTTP cached. It's best to implement
cache busting techniques. We use private caching, so
if you're iteratively building a function you can just temporarily turn your browser cache off.
This is alpha software and may be prone to bugs. Please be advised that your data is at risk
and may be lost without warning. By using Hypertext Functions you agree with our terms of service.
Hypertext Functions is currently a completely free service. The following limitations apply:
- Maximum of 3 hypertext functions per account
- Maximum of 1,000,000 versions per function
- Maximum of 500Mb of stored assets per account (including function code)
- Maximum of 100Mb of local storage per account
- Maximum of 20 calls per 30 seconds to fetch() (per organisation)
- Maximum of 10 custom domains
- Maximum of 80 environment variables
- 128Mb of memory per function call
- Timeout of 6 seconds per function call
Install Hypertext Functions CLI globally:
`bash`
npm install -g @htfn/cli
htfn login
Or run directly via npx:
`bash`
npx @htfn/cli login
If your browser doesn't automatically open when logging in, use the following flag to get the login URL and copy/paste
that into your browser instead:
`bash`
htfn login --urlor
npx @htfn/cli login --url
> IMPORTANT: Hypertext Functions CLI tool requires NodeJS version >= 18.0.0
If you have a static token (used for things like CLI processes) you can provide an access token via the HTFN_TOKEN
environment variable and this will bypass login:
`bash`
HTFN_TOKEN=
Create a simple JavaScript hypertext function file with the following contents:
`ts
// hellorld.js
export default function (request) {
const name = new URL(request.url).searchParams.get('name') ?? 'World';
return Response.json({
message: Hello ${name},`
});
}
Login to the Hypertext Functions service (authorization is currently only via GitHub - so you'll need a GitHub account
to proceed).
`bash`
htfn loginor use this flag to get the login URL instead
htfn login --url
Deploy the function that we defined above.
`bash`
htfn deploy hellorld ./hellorld.js
If the deployment was a success, you'll be presented with a set of URLs to access your new function. The URL will look
something like this:
`text`
https://hellorld-68efe810aa4648b8.fn.htfn.io/?name=Joe
Monitor the logs for a hypertext function. Logs contain messages from console.log() as well as system events:
`bash`
htfn log tail hellorld
List all of your deployed functions:
`bash`
htfn list
Filter functions by name:
`bash`
htfn list --filter=hellorld
Display more information about each function in the list:
`bash`
htfn list --extended
Get the list of functions as JSON:
`bash`
htfn list --json
List versions of a particular hypertext function:
`bash`
htfn versions hellorld
Filter function versions by contents of the push message:
`bash`
htfn versions hellorld --filter="critical update"
Display more information about each function version in the list:
`bash`
htfn versions hellorld --extended
Get the list of function versions as JSON:
`bash`
htfn versions hellorld --json
Build and bundle a given function, sending the built JavaScript to stdout:
`bash`
htfn build ./hellorld.js
Hypertext Functions CLI tool is also bundled with ESBuild, so you can build TypeScript functions too :)
`bash`
htfn build ./hellorld.ts
When you want to build and upload a new function version without making the new version "production":
`bash`
htfn push hellorld ./hellorld.ts
Push the new version with an associated message:
`bash`
htfn push hellorld ./hellorld.ts --message="did some stuff and things"
Push a new function version without building first, just upload the function as-is:
`bash`
htfn push hellorld ./hellorld.ts --no-build
Build & push a new function version, then promote the new version to "production":
`bash`
htfn push hellorld ./hellorld.ts --promote
Sometimes you may have a frontend bundle that your function may access when running
in the client. E.g. let's say you build a server-side rendered ReactJS SPA that has some client-side code, you
can build, bundle and push this as an asset too:
> Note that the "client" file, in this case App.tsx, must be in the root of your function directory
`bash`
htfn push hellorld ./hellorld.ts --client=./App.tsx
Promote any version of a hypertext function to be the "production" version.
Promote the "latest" function version to production:
`bash`
htfn promote hellorld --latest
Promote a particular function version to production, by passing the version ID:
`bash`
htfn promote hellorld --version=TuetYWNHhmuSQ3xPoVLv9M
You can prune a given hypertext function, whereby all non-production versions will be
permanently deleted:
`bash`
htfn prune hellorld
You may also upload a directory of assets (e.g. images, fonts, etc.) that will be served from the
root of your function URL:
> Note that in the following example there's a directory named assets containing the assets you wish
> to upload
`bash`
htfn push hellorld ./hellorld.ts --assets=./assets
Putting it altogether - instead of building, pushing and promoting as separate commands, you can simply run the deploy
command to perform all of these things at once; build, push & promote at the same time:
`bash`
htfn deploy hellorld ./hellorld.ts --assets=./assets --client=./App.tsx
You can permanently delete functions by removing them like so:
`bash`
htfn remove hellorld
Where hellorld is the name of your function.
If you like to live dangerously, you can forcefully remove functions immediately:
`bash`
htfn remove hellorld --force
You can add arbitrary domains to your hypertext functions, making your function production versions easier and more
memorable to access. At the moment, you can only add subdomains of htfn.io.
Add a domain to the existing hypertext function, hellorld:
`bash`
htfn domains add hellorld myfunction.htfn.io
List domains for the hypertext function, hellorld:
`bash`
htfn domains list hellorld
Remove a domain from the hypertext function, hellorld:
`bash`
htfn domains remove hellorld myfunction.htfn.io
You can add the following types of environment variables:
- Organisation - env vars available to all of your hypertext functions
- Function - env vars available to a particular hypertext function
Function env vars trump organisation env vars. All env vars are strings.
Environment vars may be accessed via the process.env object in your hypertext function, like so:
`ts`
export default function () {
return Response.json({ my_var_one: process.env.MY_VAR_ONE });
}
In order to set a value for MY_VAR_ONE:
`bashSet function env var
htfn env set func hellorld -e MY_VAR_ONE='val1'
$3
List env vars for a particular function:
`bash
htfn env list func hellorld
`List env vars for a your organisation:
`bash
htfn env list org
`$3
Remove a function env var
`bash
htfn env remove func hellorld -e MY_VAR_ONE
`Remove an organisation env var
`bash
htfn env remove org -e MY_VAR_ONE
`Logs
You can watch the tail of a particular hypertext function's log:
$3
`bash
htfn log tail hellorld
`Filter by log level:
`bash
htfn log tail hellorld --level=error
`Output JSON:
`bash
htfn log tail hellorld --json
`Only show log entries from a given date/time:
`bash
htfn log tail hellorld --from="2024-02-26 15:08:18"
`$3
You can search the log by request ID (found in the response header of a called function):
`bash
htfn log find FRAMwPMUKfX8kmwDyW8Evc
`Output JSON:
`bash
htfn log find FRAMwPMUKfX8kmwDyW8Evc --json
`Filter by log level:
`bash
htfn log find FRAMwPMUKfX8kmwDyW8Evc --level=error
`Miscellaneous
Some other hypertext function CLI commands that don't quite fit the categories above.
$3
Get details about your Hypertext Functions account and profile
`bash
htfn whoami
`$3
Log out of all of your active sessions, deleting all sessions in the process:
`bash
htfn logout
`$3
View the Hyptertext Functions terms of service (opens in your browser):
`bash
htfn terms
`$3
Opens the Hypertext Functions contact form in your browser:
`bash
htfn contact
`Function Examples
Some hypertext function ideas to get you started :)
$3
`ts
// simplejson.tsexport default function (req: Request): Response {
return Response.json({ message: "Hellorld!" });
}
``bash
htfn deploy simplejson ./simplejson.ts
`---
$3
`ts
// simplehtml.tsexport default function (req: Request): Response {
return new Response(
Hellorld!, { headers: {
"content-type": "text/html",
}});
}
``bash
htfn deploy simplehtml ./simplehtml.ts
`---
$3
`ts
// simplefetch.tsexport default async function (req: Request) {
const res = await fetch("https://example.com");
return new Response(await res.text(), { headers: {
"content-type": "text/html",
}});
}
``bash
htfn deploy simplefetch ./simplefetch.ts
`---
$3
`ts
// myip.tsexport default function (req: Request) {
return Response.json({
your_ip: req.headers.get('x-real-ip'),
});
}
``bash
htfn deploy myip ./myip.ts
`---
$3
`ts
// storage.tsexport default function (req: Request) {
const message = new URL(req.url).searchParams.get('message') ?? 'default message';
// Make use of the full localStorage API, not just setItem() :)
// The local storage item "my_message" will be available in all of your hypertext functions
localStorage.setItem("my_message", message);
return Response.json({ message: localStorage.getItem("my_message") });
}
``bash
htfn deploy storage ./storage.ts
`---
$3
`ts
// randomuuid.tsexport default function (req: Request) {
return Response.json({
random_uuid: self.crypto.randomUUID(),
});
}
``bash
htfn deploy randomuuid ./randomuuid.ts
`---
$3
Use the Hono framework to build a REST API:
`bash
npm init
npm install hono
``ts
// hono.tsimport { Hono } from 'hono';
const app = new Hono();
app.get('/users', (c) => c.json([{ name: 'Joe Bloggs' }]));
export default app.fetch;
``bash
htfn deploy hono ./hono.ts
``---
More examples to follow...