JSflare is a simple command-line tool that keeps your Cloudflare DNS records updated with your current public IP address. Ideal for users with dynamic IPs who want to host services at home, it supports both Cloudflare API keys and tokens for secure authentication. Configure it easily with a JSON file and let it handle the rest.
Cloudflare hosts your DNS records (besidees a bunch of other things). This script will update your DNS record with your current public IP address. This is useful if you have a dynamic IP address and want to host a server at home.
The script is intended to be directly called from the command line - although you could import it as a module if you wanted to.
The script requires a configuration file config.jsonc or config.json to be present. Take the provided example_config.jsonc as an example and fill in the required fields.
To run the script with Node.js you have to install the dependencies first.
This can be done with the following commands. (The repository uses pnpm as package manager, but you can use npm as well.). Afterwards, the TypeScript code can be directly run with a supported Node.js version.
pnpm install
node src/index.tsYou can also run the script in a Docker container. This allows you to run the script on any system that supports Docker without having to worry about dependencies or Node.js versions. To run the script in a container, utilize the image from Docker Hub, which you can run via the following command:
docker run --rm \
-v /path/to/config.jsonc:/config/config.jsonc:ro \
mrminemeet/jsflareor with Podman:
podman run --rm --network=host \
-v ./config.jsonc:/config/config.jsonc:ro \
mrminemeet/jsflareThe configuration file is a JSON file that contains the necessary information to update the DNS records. The required fields are:
items(array): List of DNS records to update. Each item supports:token(string, optional): Cloudflare API token for the zone (preferred).email(string, optional): Cloudflare account email (legacy key auth).key(string, optional): Cloudflare API key (legacy key auth).zone(string): The zone name (e.g.,domain.example).record(string): The full DNS record name to update (e.g.,host.domain.example).ttl(number): TTL in seconds.1means automatic. Valid range is 60-86400.proxied(boolean): Whether the record is proxied through Cloudflare.
postUpdateWebhook(string, optional): URL to POST to after each update attempt, with the results.
Notes:
- Provide either
tokenoremail+keyfor each item. itemscan contain a mix of token and legacy key entries.
If postUpdateWebhook is set, the script will send a POST request to the specified URL.
This update is triggered on each run, so even when nothing was updated. The idea is to allow users to see if the script is actually running (e.g. health checks).
The payload will be a JSON object with the following structure:
The script can work with either the legacy API keys or the new API tokens. The prefered way are the tokens, which are more secure and can be more granularly controlled, and in general limit actions to the required minimum.
Independent of the used method, the key/token can be viewed/generated in the Cloudflare dashboard.
To use the legacy API keys, you need to provide the email and key fields in the configuration file. This method does not provide any restrictions on the actions that can be taken with the API key. So it is recommended to use the API tokens.
To use the API tokens, you need to provide token fields in the configuration file. The token can be generated in the dashboard.
The token needs the following permission:
- All zones - Zone:Read, DNS:Edit
To run the script periodically, you can use a systemd timer and service. There are other ways to run the script periodically, but this is the most common way on most Linux systems.
To call the script every N minutes, create a file /etc/systemd/system/jsflare.timer with the following content:
[Unit]
Description=Run JSflare DNS update service
[Timer]
# Run every 10 minutes
OnCalendar=*:0/10
Persistent=true
[Install]
WantedBy=timers.targetThe service that actually runs the script should be created in /etc/systemd/system/jsflare.service.
The value of WorkingDirectory should be the path to the repository was cloned to.
[Unit]
Description=JSflare DNS Update Service
After=network.target
[Service]
Type=simple
WorkingDirectory=<SET THIS VALUE>
ExecStart=/usr/bin/node ./dist/index.js
[Install]
WantedBy=multi-user.target- ipify is used to get the public IP address.
- icanhazip is used as another service to get public IP address.
- Axios is used to make HTTP requests to the Cloudflare API and the webhook.
This project is licensed under the MIT License - see the LICENSE file for details.
{ "timestamp": "2026-01-01T00:00:00.000Z", // ISO string of the time the update was attempted "publicIp": "1.2.3.4", // The public IP address that was detected "records": [ { "record": "host1.domain.example", // The record that was updated, "success": true, // Whether the update was successful // No "error" when update was successful }, { "record": "host2.domain.example", // The record that was updated, "success": false, // Whether the update was successful "error": "Failed to update record" // If the update failed, this will contain the error message } ] }