Skip to main content
Skip table of contents

VFace Web

VFace Web is a Javascript library which brings VFace to the web in modern web browsers. VFace Web has the same capabilities as VFace on mobile; the same C++ codebase which powers the mobile versions of VFace is compiled to WebAssembly.

Integration Into a Web App

VFace Web is provided as an NPM package, which allows for easy integration into web apps built with bundler tools like Webpack. If you're not using a bundler (or are using a bundler and are having problems), see the Not using a bundler section.

Install the vface-web library:

npm install ./vface-web.tgz

The library is a standard EcmaScript (ES) module, so it can easily be used from your javascript code with the standard import mechanisms, for example:

import { VFaceWeb } from "vface-web";
let vface = new VFaceWeb({
    // Other options are documented in the 
    // "Additional Constructor Options" section.
    licence: "licence_string"

where licence string is your VFace licence obtained from Veridium.

The vface object can then be used to acquire templates for enrol or authentication like so:

let authenticate_promise = vface.authenticateGetTemplate();
let enroll_promise = vface.enroll();

which causes the UI to be presented to acquire the face.

These two methods return promises that resolve to strings containing the template data, as Base64 encoded Data URLs, if they are successful. If there is a failure the promises will be rejected with an error. Information is available in the returned error as to the exact nature of the failure, but it is not recommended to present that information to the user at this time.

An example:

vface.authenticateGetTemplate().then(value => {
    alert(`Got template! It's got a length of: ${value.length}!`);
}).catch(reason => {
    alert(`Failed to get template! ${JSON.stringify(reason)}`);

Configuration Options

The enrol and authenticate methods can take configuration options. For example:

let authenticate_promise = vface.authenticateGetTemplate({
  config: {
    liveness: false,
    liveness_factor: 49

The available options are as follows:






Set true to enable liveness



Control liveness security level. See liveness factors



Set true to enable export of an aligned face image.

Image Export

Configure the enrolment promise with option with_export true to include the aligned face image in the enrol template:

let json_config_string = "{}";
let enrol_promise = vface.enroll({
  config: {
    liveness: true,
    with_export: true

Decode the resulting template from Base64 to retrieve the zip encoded file, and uncompress. See VFace Export for details regarding the file structure and face image.

Not Using a Bundler

If you are using a bundler (like Webpack) and everything works, you can skip this section.

At runtime, the main vface-web.js file has to be able to fetch and import vface-web-worker.js and the .wasm files. By default, it will try to find these files using import.meta.url as a base URL. This means that these files must be siblings in the directory structure.

For example, if vface-web.js is available at, then the other files should be at and, etc.

Alternatively, you can provide paths for vface-web-worker.js and the .wasm files using the url options in the constructor.

Camera Selection

If more than one camera is available on the device, a dropdown box appears in the UI which allows selection of the camera in use. The default is to use a camera chosen by the browser.

The user-selected camera will be remembered and used when the same set of cameras is seen in the future.


The additional_css option can be used to inject CSS styles to customise the appearance of the UI. An example is to change the accent colour used for some UI elements to   hotpink:

let vface = new VFaceWeb({
    additional_css: ".vface {--accent-color: hotpink; }"

To make it easier to see the effect of changing various CSS styles, you can use the UI zoo method, which will present the UI and cycle through various possible states of the interface.


This displays the following (cycling through states not shown):

VFace UI with hotpink accent colour


The library has built-in support for English, French, and Spanish localisations, which will be automatically selected based on the user's browser language.

To override the automatically selected language, or to modify the built-in translations, the localisation option of the VFace Web constructor can be used to override individual localisation tokens. The full list of localisation tokens is available in the localisation tokens section of this document.

Code documentation

The following documentation is also available in the vface-web.d.ts file distributed inside the vface-web.tgz file.

Constructor Options

As well as the options mentioned previously, the following options can be provided to the VFaceWeb constructor:

/** VFace licence string. */
licence?: string | Promise<string>;

/** Optional URL for vface-web-worker.js 
 * The library will discover the correct path for this file in most 
 * circumstances.  This only needs to be set if that discovery doesn't 
 * work. */
worker_url?: string | Promise<string>;

/** Optional URL for vface_web_runtime.wasm 
 * The library will discover the correct path for this file in most 
 * circumstances.  This only needs to be set if that discovery doesn't 
 * work. */
wasm_url?: string | Promise<string>;

/** Optional URL for vface_web_runtime_simd.wasm 
 * The library will discover the correct path for this file in most 
 * circumstances.  This only needs to be set if that discovery doesn't 
 * work. */
wasm_simd_url?: string | Promise<string>;

/** Specifies the level of logging emitted by the library.
 * Ordered by least verbose to most verbose. */
log_level?: "silence" | "error" | "warning" | "log" | "verbose";

/** Specifies the UI to extend all the way to the edges of the page,
 * rather than appearing in a floating box. */
ui_full_bleed?: boolean;

/** The VFace UI is normally injected into a shadow DOM; this option
 * causes it to be injected into the regular DOM. */
ui_no_shadow_dom?: boolean;

/** Override specific localisation tokens 
 * The library has built-in localisations for English, Spanish and 
 * French, which will be selected automatically based on the user's 
 * browser language. Those localisations can be overriden on a
 * per-token basis using this option.
localisation?: { [Key in LocalisationToken]: string };

/** Used to disable the functionality for selecting a camera. */
disable_camera_select?: boolean;

/** Additional CSS which will be appended after the built-in styling.
 * This allows the styling of the UI to be customised.
 * Use {@link IVFaceWeb.uiZoo} to test that custom styling appears 
 * correctly for all possible UI states.
additional_css?: string;

/** Allows the remember camera functionality to be switched on or off. 
 * Defaults to `true`
 * The remember camera functionality uses local storage to remember the 
 * user's preferences for camera selection.
remember_camera?: boolean;

Methods on VFaceWeb object

interface Config {
    liveness?: boolean;
    liveness_factor?: number;
    packDevData?: boolean;
    with_export?: boolean;

interface CommonOptions {
    /** Configuration options */
    config?: Config;

export interface EnrollOptions extends CommonOptions {

export interface AuthOptions extends CommonOptions {

export interface IVFaceWeb {
    /** Presents the VFace Web UI to enroll (generate an enrollment
     * template for) a user.
     * @returns A promise which resolves with a string containing a 
     * data: URL for the template.
     * Rejects with a {@link VFaceError}  */
    enroll(options?: EnrollOptions): Promise<string>;

    /** Presents the VFace Web UI to generate an authentication
     * template for a user.
     * @returns A promise which resolves with a string containing a
     * data: URL for the template.
     * Rejects with a {@link VFaceError}  */
    authenticateGetTemplate(options?: AuthOptions): Promise<string>;

    /** Presents the VFace Web UI to authenticate a user.
     * !!! NOTE: Only available if the VFace Web build includes the 
     * matching model, which is *not* the default.
     * @returns A promise which resolves to true if the user matches 
     * the provided enrollment template.
     * Rejects with a {@link VFaceError} */
    authenticate(template: string | Promise<string>, options?: AuthOptions): Promise<boolean>;

    /** Set the licence for the VFace library, if it wasn't set in the 
     * constructor */
    setLicence(licence: string | Promise<string>): Promise<void>;

    /** Get the version number of VFace Web. */
    version(): string;

    /** Get the git commit id that this version of VFace Web was built 
     * from. */
    git_version(): string;

    /** Displays the UI zoo, which randomly cycles through many
     * possible states for the VFace Web UI.
     * This is to verify that the UI is styled correctly, especially
     * when using the `additional_css` option in the constructor.
     * @returns A dummy promise, to match the return types of the
     * enroll and authenticate functions. */
    uiZoo(): Promise<string>;


In case of issues, set the log_level option to log or verbose, this will print errors and other diagnostic information to the console. It may be immediately obvious from the errors what the problem is, but if not, the diagnostic information can be provided to Veridium to help diagnose the issue.

Appendix: Localisation tokens

Localisation token

Default English translation



Can't find a face


Move further away


Move closer


Move down


Move up


Move left


Move right


Stay upright


Face the camera


Stay still


Need brighter image


Need darker image


Stay still facing the camera




Remove sunglasses


Please face to your left


Please face to your right


Please face up


Please face down


VFace Authentication




Toggle spoken instructions


Speech on!




Loading VFace:


Camera access not allowed, please allow camera access and refresh.


No camera connected. Please connect a camera and try again.




VFace Web Help


Avoid strong backlighting


Avoid harsh lighting and shadow on face


Turn to face each direction indicator as requested


Keep head movements gentle


Don't turn too far; only turn until the movement is recognised


Please try again, face the camera

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.