OpenAge runs face tracking, liveness checks, and age estimation on-device. Use it as a drop-in age gate with a checkbox-style widget, modal flow, or button binding.
| Browser-side | Server-backed | UI |
|---|---|---|
| On-device face analysis | Optional WASM verification | Widget popup, inline embed, bind |
| No raw camera upload | Signed sessions and tokens | Normal, compact, invisible |
| Serverless soft gates | Hosted or custom backend | Auto, light, dark |
npm install @tn3w/openage<script src="https://cdn.jsdelivr.net/npm/@tn3w/openage/dist/openage.min.js"></script><div class="openage" data-sitekey="ag_live_xxxx" data-callback="onVerified"></div>
<script src="https://cdn.jsdelivr.net/npm/@tn3w/openage/dist/openage.min.js"></script>
<script>
function onVerified(token) {
console.log('verified', token);
}
</script>import OpenAge from '@tn3w/openage';
OpenAge.render('#gate', {
mode: 'serverless',
layout: 'inline',
minAge: 18,
callback: (token) => console.log(token),
errorCallback: (error) => console.error(error),
});OpenAge.render('#gate', {
mode: 'serverless',
layout: 'inline',
minAge: 18,
});layout: 'inline' removes the checkbox shell and renders the verification
panel directly in the container. The first verification step starts
immediately after loading.
OpenAge.bind('#buy-btn', {
sitekey: 'ag_live_xxxx',
callback: (token) => submitForm(token),
});| Mode | Backend | Use case |
|---|---|---|
serverless |
none | client-only soft gates |
sitekey |
OpenAge hosted | production verification |
custom |
your server | self-hosted verification |
serverless keeps everything local and returns a client-signed token.
sitekey and custom use a server session and a WASM VM for stronger checks.
OpenAge.render(container, params);
OpenAge.open(params);
OpenAge.bind(element, params);
OpenAge.reset(widgetId);
OpenAge.remove(widgetId);
OpenAge.getToken(widgetId);
OpenAge.execute(widgetId);
await OpenAge.challenge(params);Runtime errors keep the popup open long enough to explain what happened. If no camera is available, OpenAge tells the user to plug one in and closes the popup automatically after 5 seconds.
| Param | Values |
|---|---|
mode |
serverless, sitekey, custom |
layout |
widget, inline |
theme |
light, dark, auto |
size |
normal, compact, invisible |
minAge |
number, default 18 |
sitekey |
required for hosted mode |
server |
required for custom mode |
- Static demo: https://tn3w.github.io/OpenAge/
- Local server demo:
cd server
pip install -r requirements.txt
python server.pyThe repository also includes demo/, a minimal GitHub Pages build that loads
the jsDelivr bundle for @tn3w/openage in inline embedded serverless mode.
npm install
npm test
npm run build
npm run devOptional server:
cd server
pip install -r requirements.txt
python server.pypip install black isort
isort . && black .
npx prtfm
clang-format -i server/wasm/src/*.c server/wasm/src/*.h