Skip to content
dnsdist logo

Dnsdist

dnsdist

DNS load balancer with DoS protection, multi-protocol support (DoH, DoT, DoQ), and dynamic traffic management

SKILL.md

Full skill instructions

dnsdist

High-performance DNS load balancer from PowerDNS that distributes queries across backend servers while providing DoS protection, caching, and support for encrypted DNS protocols (DoH, DoT, DoQ, DNSCrypt).

Overview

dnsdist is a DNS-aware, DoS-aware load balancer that receives DNS queries and intelligently routes them to backend servers based on configurable policies. It operates at the DNS protocol level, enabling sophisticated traffic management, abuse prevention, and protocol translation.

Key Capabilities

  • Load Balancing: Distribute queries across multiple DNS backends
  • DoS Protection: Dynamic blocking, rate limiting, eBPF filtering
  • Multi-Protocol: Do53, DNS-over-TLS, DNS-over-HTTPS, DNS-over-QUIC, DNSCrypt
  • Response Caching: Built-in packet cache with stale serving
  • Dynamic Configuration: Runtime changes via Lua console
  • Monitoring: Prometheus metrics, REST API, Carbon export

Installation

Package Managers

Debian/​Ubuntu:

apt-get install -y dnsdist

RHEL/​CentOS:

yum install -y epel-release
yum install -y dnsdist

FreeBSD:

pkg install dns/​dnsdist

From Source

# Dependencies: C++17 compiler, Boost, Lua 5.1+, libedit

# From tarball
wget https://downloads.powerdns.com/​releases/​dnsdist-X.Y.Z.tar.bz2
tar xf dnsdist-X.Y.Z.tar.bz2
cd dnsdist-X.Y.Z
./​configure
make
sudo make install

# From Git
git clone https://github.com/​PowerDNS/​pdns.git
cd pdns/​pdns/​dnsdistdist
autoreconf -i
./​configure
make

Verify Installation

dnsdist --version
# Check for: dns-over-tls(DOT) dns-over-https(DOH) dnscrypt

Quick Start

Basic Command Line

# Listen on port 5300, forward to Quad9 servers
dnsdist -l 127.0.0.1:5300 9.9.9.9 2620:fe::fe 2620:fe::9

Minimal Configuration

Create dnsdist.conf:

-- Listen on standard DNS port
setLocal("0.0.0.0:53")

-- Add backend servers
newServer({address="9.9.9.9", name="quad9-primary"})
newServer({address="1.1.1.1", name="cloudflare"})

-- Set load balancing policy
setServerPolicy(firstAvailable)

-- Access control (default: RFC1918 ranges)
setACL({"0.0.0.0/​0", "::/​0"})  -- Allow all (be careful!)

Run with configuration:

dnsdist -C dnsdist.conf

Backend Server Configuration

Adding Servers

-- Basic server
newServer("192.168.1.10")

-- Server with options
newServer({
  address = "192.168.1.10:53",
  name = "dns-primary",
  qps = 100,                    -- Max queries per second
  order = 1,                    -- Selection order
  weight = 100,                 -- Load balancing weight
  retries = 2,                  -- Retry attempts
  tcpConnectTimeout = 5,        -- TCP connect timeout (seconds)
  tcpSendTimeout = 30,          -- TCP send timeout
  tcpRecvTimeout = 30,          -- TCP receive timeout
  checkInterval = 1,            -- Health check interval
  checkTimeout = 1000,          -- Health check timeout (ms)
  maxCheckFailures = 3,         -- Failures before marking down
  mustResolve = true,           -- Must resolve check name
  checkName = "health.example.com",
  rise = 2,                     -- Successes before marking up
  useClientSubnet = true,       -- Forward EDNS Client Subnet
  pool = "primary"              -- Assign to pool
})

-- Server with DNS-over-TLS backend
newServer({
  address = "1.1.1.1:853",
  tls = "openssl",              -- or "gnutls"
  subjectName = "cloudflare-dns.com",
  validateCertificates = true
})

-- Server with DNS-over-HTTPS backend
newServer({
  address = "1.1.1.1:443",
  tls = "openssl",
  dohPath = "/​dns-query",
  subjectName = "cloudflare-dns.com"
})

Server Pools

-- Create pools for different purposes
newServer({address="192.168.1.10", pool="recursive"})
newServer({address="192.168.1.11", pool="recursive"})
newServer({address="10.0.0.50", pool="authoritative"})

-- Route queries to specific pools
addAction(QNameSuffixRule("internal.example.com"), PoolAction("authoritative"))
addAction(AllRule(), PoolAction("recursive"))

Server Management

-- Console commands
showServers()                   -- Display all servers
getServer(0):setUp()            -- Force server up
getServer(0):setDown()          -- Force server down
getServer(0):setQPS(50)         -- Change QPS limit
getServer(0):addPool("backup")  -- Add to pool
rmServer(0)                     -- Remove server

Load Balancing Policies

Built-in Policies

-- First available (default)
setServerPolicy(firstAvailable)

-- Round robin
setServerPolicy(roundrobin)

-- Least outstanding queries
setServerPolicy(leastOutstanding)

-- Weighted random
setServerPolicy(wrandom)

-- Weighted round robin
setServerPolicy(whashed)

-- Random
setServerPolicy(random)

-- Consistent hashing (sticky by client IP)
setServerPolicy(chashed)

Custom Policy

-- Custom Lua policy function
function myPolicy(servers, dq)
  -- Route .internal queries to first server
  if dq.qname:isPartOf(newDNSName("internal.")) then
    return servers[1]
  end
  -- Round robin for everything else
  return leastOutstanding.policy(servers, dq)
end

setServerPolicyLua("myPolicy", myPolicy)

Per-Pool Policies

getPool("recursive"):setPolicy(leastOutstanding)
getPool("authoritative"):setPolicy(roundrobin)

Rules and Actions

Rule Selectors

-- Match by query name
QNameRule("example.com")              -- Exact match
QNameSuffixRule("example.com")        -- Suffix match
QNameSetRule(newSuffixMatchNode())    -- Set-based match
RegexRule(".*\\.example\\.com$")      -- Regex match

-- Match by query type
QTypeRule(DNSQType.ANY)
QTypeRule(DNSQType.AXFR)

-- Match by source
NetmaskGroupRule(nmg)                 -- IP ranges
MaxQPSIPRule(10, 32, 48)             -- Rate per IP (IPv4/​32, IPv6/​48)
MaxQPSRule(1000)                      -- Global rate

-- Match by protocol
TCPRule(true)                         -- TCP queries
DNSSECRule()                          -- DNSSEC queries

-- Match by response code
RCodeRule(DNSRCode.NXDOMAIN)
RCodeRule(DNSRCode.SERVFAIL)

-- Compound rules
AndRule({QTypeRule(DNSQType.ANY), MaxQPSIPRule(1)})
OrRule({QNameRule("blocked1.com"), QNameRule("blocked2.com")})
NotRule(NetmaskGroupRule(allowedNmg))

Actions

-- Routing actions
PoolAction("poolname")                -- Route to pool
newServer({...})                      -- Direct to server

-- Response actions
DropAction()                          -- Drop query silently
RefusedAction()                       -- Return REFUSED
NXDomainAction()                      -- Return NXDOMAIN
SpoofAction("192.168.1.1")           -- Spoof A record
SpoofCNAMEAction("cname.example.com") -- Spoof CNAME

-- Modification actions
SetNoRecurseAction()                  -- Clear RD flag
DelayAction(100)                      -- Delay response (ms)
TCAction()                            -- Force TCP (set TC bit)
LogAction("/​var/​log/​queries.log")     -- Log query

-- Rate limiting
DelayAction(500)                      -- Slow down client
SetEDNSOptionAction(8, "value")       -- Add EDNS option

Adding Rules

-- Add rule with action
addAction(MaxQPSIPRule(10), DelayAction(200))
addAction(QTypeRule(DNSQType.ANY), DropAction())
addAction(QNameSuffixRule("blocked.com"), RefusedAction())

-- Rule with logging
addAction(MaxQPSIPRule(50), LogAction("/​var/​log/​ratelimit.log", false, true))

-- Rule ordering (insert at position)
addAction(QNameRule("priority.com"), PoolAction("fast"), 0)

-- Response rules
addResponseAction(RCodeRule(DNSRCode.SERVFAIL), LogAction())

-- Cache hit rules
addCacheHitResponseAction(...)

Rule Management

showRules()                           -- List all rules
rmRule(0)                             -- Remove rule by index
mvRule(0, 5)                          -- Move rule position
clearRules()                          -- Remove all rules
topRules()                            -- Show rule hit stats

DNS-over-TLS (DoT)

Incoming DoT

-- Basic DoT listener
addTLSLocal("0.0.0.0:853",
  "/​etc/​ssl/​certs/​dns.example.com.pem",
  "/​etc/​ssl/​private/​dns.example.com.key"
)

-- With options
addTLSLocal("0.0.0.0:853",
  "/​etc/​ssl/​certs/​dns.pem",
  "/​etc/​ssl/​private/​dns.key",
  {
    minTLSVersion = "tls1.2",
    ciphers = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384",
    numberOfTicketsKeys = 5,
    ticketKeyFile = "/​etc/​dnsdist/​ticket.key",
    sessionTickets = true,
    numberOfStoredSessions = 20000
  }
)

-- Multiple certificates (ECDSA + RSA)
addTLSLocal("0.0.0.0:853",
  {"/​etc/​ssl/​certs/​dns.ecdsa.pem", "/​etc/​ssl/​certs/​dns.rsa.pem"},
  {"/​etc/​ssl/​private/​dns.ecdsa.key", "/​etc/​ssl/​private/​dns.rsa.key"}
)

Outgoing DoT

-- Forward to DoT backend
newServer({
  address = "1.1.1.1:853",
  tls = "openssl",
  subjectName = "cloudflare-dns.com",
  validateCertificates = true
})

-- With certificate pinning
newServer({
  address = "9.9.9.9:853",
  tls = "openssl",
  subjectName = "dns.quad9.net",
  validateCertificates = true,
  caStore = "/​etc/​ssl/​certs/​quad9.pem"
})

DNS-over-HTTPS (DoH)

Incoming DoH

-- Basic DoH listener
addDOHLocal("0.0.0.0:443",
  "/​etc/​ssl/​certs/​dns.pem",
  "/​etc/​ssl/​private/​dns.key",
  "/​dns-query"
)

-- With options
addDOHLocal("0.0.0.0:443",
  "/​etc/​ssl/​certs/​dns.pem",
  "/​etc/​ssl/​private/​dns.key",
  "/​dns-query",
  {
    minTLSVersion = "tls1.2",
    customResponseHeaders = {["X-Custom"] = "value"},
    serverTokens = "dnsdist",
    trustForwardedForHeader = false
  }
)

-- Behind reverse proxy (HTTP only)
addDOHLocal("127.0.0.1:8053")

Outgoing DoH

newServer({
  address = "1.1.1.1:443",
  tls = "openssl",
  dohPath = "/​dns-query",
  subjectName = "cloudflare-dns.com",
  validateCertificates = true
})

DNS-over-QUIC (DoQ)

-- DoQ listener (port 853 UDP)
addDOQLocal("0.0.0.0:853",
  "/​etc/​ssl/​certs/​dns.pem",
  "/​etc/​ssl/​private/​dns.key"
)

-- DNS-over-HTTP/​3
addDOH3Local("0.0.0.0:443",
  "/​etc/​ssl/​certs/​dns.pem",
  "/​etc/​ssl/​private/​dns.key",
  "/​dns-query"
)

Response Caching

Basic Cache Setup

-- Create cache with 100,000 entries
pc = newPacketCache(100000, {
  maxTTL = 86400,              -- Max TTL (1 day)
  minTTL = 60,                 -- Min TTL (1 minute)
  temporaryFailureTTL = 60,    -- SERVFAIL cache time
  staleTTL = 3600,             -- Stale serving window
  dontAge = false,             -- Age cached responses
  numberOfShards = 1,          -- Parallelism
  deferrableInsertLock = true, -- Performance optimization
  maxNegativeTTL = 3600,       -- NXDOMAIN cache time
  parseECS = true              -- ECS-aware caching
})

-- Attach to default pool
getPool(""):setCache(pc)

-- Pool-specific cache
recursiveCache = newPacketCache(50000)
getPool("recursive"):setCache(recursiveCache)

Cache Management

-- View statistics
getPool(""):getCache():printStats()

-- Purge entries
getPool(""):getCache():purgeExpired(0)
getPool(""):getCache():expunge(1000)  -- Remove oldest 1000

-- Remove specific entries
getPool(""):getCache():expungeByName(newDNSName("example.com"))
getPool(""):getCache():expungeByName(newDNSName("example.com"), DNSQType.A)

-- Remove cache from pool
getPool(""):unsetCache()

DoS Protection

Dynamic Blocking Rules

-- Create dynamic blocking rules group
local dbr = dynBlockRulesGroup()

-- Rate limiting rules
dbr:setQueryRate(100, 10, "Query rate exceeded", 60)
-- Block if >100 qps over 10 seconds, for 60 seconds

dbr:setRCodeRate(DNSRCode.NXDOMAIN, 50, 10, "NXDOMAIN rate exceeded", 300)
dbr:setRCodeRate(DNSRCode.SERVFAIL, 20, 10, "SERVFAIL rate exceeded", 300)

-- Query type rate limiting
dbr:setQTypeRate(DNSQType.ANY, 5, 10, "ANY query rate exceeded", 60)

-- Response bandwidth rate
dbr:setResponseByteRate(10000000, 10, "Bandwidth exceeded", 60)
-- Block if >10MB/​s over 10 seconds

-- Exclude trusted ranges
dbr:excludeRange(newNMG({"10.0.0.0/​8", "192.168.0.0/​16"}))

-- Apply in maintenance function (called every second)
function maintenance()
  dbr:apply()
end

Manual Blocking

-- Block specific address
addDynamicBlock(newCA("192.0.2.1"), "Manual block", 3600)

-- Block with action
addDynamicBlock(newCA("192.0.2.0/​24"), "Subnet block", 3600, DNSAction.Refused)

-- View active blocks
showDynBlocks()

-- Clear all blocks
clearDynBlocks()

-- Clear specific block
rmDynBlocks(newCA("192.0.2.1"))

eBPF Filtering (High Performance)

-- Create eBPF filter
bpf = newBPFFilter({
  ipv4MaxItems = 100000,
  ipv6MaxItems = 100000,
  qnamesMaxItems = 10000,
  mapDir = "/​sys/​fs/​bpf/​dnsdist"  -- Persistent maps
})

-- Attach to frontend
bpf:attachToAllBinds()

-- Create dynamic eBPF filter
dynbpf = newDynBPFFilter(bpf)

-- Use with dynamic blocking
dbr:setQueryRate(100, 10, "Rate exceeded", 60, DNSAction.Drop, 0, 0, dynbpf)

-- Manual eBPF blocking
bpf:block(newCA("192.0.2.1"))
bpf:blockQName(newDNSName("blocked.com"), DNSQType.ANY)

-- Unblock
bpf:unblock(newCA("192.0.2.1"))

-- Statistics
bpf:getStats()

Access Control

-- Set ACL (replaces existing)
setACL({"10.0.0.0/​8", "192.168.0.0/​16", "172.16.0.0/​12"})

-- Add to ACL
addACL("203.0.113.0/​24")

-- View ACL
showACL()

-- Require proxy protocol from load balancers
setProxyProtocolACL({"10.0.0.1/​32", "10.0.0.2/​32"})

Webserver and API

Enable Webserver

-- Basic webserver
webserver("127.0.0.1:8083")

-- With authentication
webserver("127.0.0.1:8083")
setWebserverConfig({
  password = hashPassword("supersecret"),
  apiKey = hashPassword("apikey123"),
  acl = "127.0.0.1/​8, ::1/​128",
  dashboardRequiresAuthentication = true,
  statsRequireAuthentication = false
})

-- Enable API write access
setAPIWritable(true, "/​etc/​dnsdist/​acl-updates/")

API Endpoints

EndpointMethodDescription
/GETDashboard HTML
/​jsonstat?command=statsGETStatistics JSON
/​jsonstat?command=dynblocklistGETDynamic blocks
/​metricsGETPrometheus metrics
/​api/​v1/​servers/​localhostGETServer overview
/​api/​v1/​servers/​localhost/​config/​allow-fromPUTUpdate ACL
/​api/​v1/​cacheDELETEPurge cache entries

Example API Usage

# Get statistics
curl -H "X-API-Key: apikey123" http://127.0.0.1:8083/​jsonstat?command=stats

# Prometheus metrics
curl http://127.0.0.1:8083/​metrics

# Purge cache
curl -X DELETE -H "X-API-Key: apikey123" \
  "http://127.0.0.1:8083/​api/​v1/​cache?pool=&name=example.com"

Console Management

Enable Console

-- Local console socket
controlSocket("127.0.0.1:5199")

-- With authentication
setKey("base64encodedkey==")

Connect to Console

dnsdist -c 127.0.0.1:5199
# Or with key
dnsdist -c 127.0.0.1:5199 -k "base64encodedkey=="

Console Commands

-- Server management
showServers()
showPools()
getServer(0):isUp()

-- Rule management
showRules()
showResponseRules()
topRules()

-- Statistics
showBinds()
showTCPStats()
showTLSErrorCounters()
showDOHFrontends()
showDOHResponseCodes()

-- Cache
getPool(""):getCache():printStats()

-- Traffic analysis
grepq("example.com")
topQueries(20)
topResponses(20, DNSRCode.NXDOMAIN)
topClients(20)

-- Dynamic blocks
showDynBlocks()
clearDynBlocks()

-- Maintenance
dumpStats()
delta()              -- Changes since last call
quit() / exit()

Logging and Metrics

Query Logging

-- Log all queries
addAction(AllRule(), LogAction("/​var/​log/​dnsdist/​queries.log", false, true))

-- Log rate-limited queries
addAction(MaxQPSIPRule(10), LogAction("/​var/​log/​ratelimit.log"))

-- Remote logging (dnstap)
dnstapLog = newFrameStreamUnixLogger("/​var/​run/​dnstap.sock")
addAction(AllRule(), DnstapLogAction("dnsdist", dnstapLog))
addResponseAction(AllRule(), DnstapLogResponseAction("dnsdist", dnstapLog))

Carbon/​Graphite Export

carbonServer("graphite.example.com:2003", "dnsdist.node1", 10)
-- Host, prefix, interval (seconds)

Prometheus Metrics

Access at http://server:8083/​metrics:

# HELP dnsdist_queries Number of queries
# TYPE dnsdist_queries counter
dnsdist_queries 12345678

# HELP dnsdist_responses Number of responses
# TYPE dnsdist_responses counter
dnsdist_responses 12345670

# HELP dnsdist_servfail_responses ServFail responses
# TYPE dnsdist_servfail_responses counter
dnsdist_servfail_responses 100

# HELP dnsdist_latency_avg Average latency (usec)
# TYPE dnsdist_latency_avg gauge
dnsdist_latency_avg 1234.5

Configuration Examples

High-Availability DNS Load Balancer

-- dnsdist.conf - HA DNS Load Balancer

-- Frontend listeners
setLocal("0.0.0.0:53")
addTLSLocal("0.0.0.0:853", "/​etc/​ssl/​dns.pem", "/​etc/​ssl/​dns.key")
addDOHLocal("0.0.0.0:443", "/​etc/​ssl/​dns.pem", "/​etc/​ssl/​dns.key", "/​dns-query")

-- Backend servers with health checks
newServer({
  address = "192.168.1.10:53",
  name = "dns1",
  checkName = "health.internal.",
  checkInterval = 1,
  maxCheckFailures = 3,
  rise = 2,
  pool = "recursive"
})
newServer({
  address = "192.168.1.11:53",
  name = "dns2",
  checkName = "health.internal.",
  checkInterval = 1,
  maxCheckFailures = 3,
  rise = 2,
  pool = "recursive"
})

-- Load balancing
setServerPolicy(leastOutstanding)

-- Response cache
pc = newPacketCache(500000, {
  maxTTL = 86400,
  minTTL = 60,
  staleTTL = 3600
})
getPool("recursive"):setCache(pc)

-- DoS protection
local dbr = dynBlockRulesGroup()
dbr:setQueryRate(100, 10, "Query flood", 60)
dbr:setRCodeRate(DNSRCode.NXDOMAIN, 50, 10, "NXDOMAIN flood", 300)

function maintenance()
  dbr:apply()
end

-- Access control
setACL({"0.0.0.0/​0", "::/​0"})

-- Monitoring
webserver("127.0.0.1:8083")
setWebserverConfig({password = hashPassword("monitor123")})
controlSocket("127.0.0.1:5199")

Split-Horizon DNS

-- Route internal queries to internal servers
newServer({address = "10.0.0.53", pool = "internal"})
newServer({address = "10.0.0.54", pool = "internal"})

-- External recursive resolvers
newServer({address = "9.9.9.9", pool = "external"})
newServer({address = "1.1.1.1", pool = "external"})

-- Routing rules
addAction(QNameSuffixRule("internal.example.com"), PoolAction("internal"))
addAction(QNameSuffixRule("corp.example.com"), PoolAction("internal"))
addAction(AllRule(), PoolAction("external"))

-- Different policies per pool
getPool("internal"):setPolicy(roundrobin)
getPool("external"):setPolicy(leastOutstanding)

DNS Firewall with Blocklist

-- Load blocklist
blockedDomains = newSuffixMatchNode()
for line in io.lines("/​etc/​dnsdist/​blocklist.txt") do
  blockedDomains:add(newDNSName(line))
end

-- Block malicious domains
addAction(SuffixMatchNodeRule(blockedDomains), SetTagAction("blocked", "malware"))
addAction(TagRule("blocked"), NXDomainAction())

-- Rate limit ANY queries
addAction(QTypeRule(DNSQType.ANY), DropAction())

-- Limit AXFR attempts
addAction(QTypeRule(DNSQType.AXFR), RefusedAction())

-- Log blocked queries
addAction(TagRule("blocked"), LogAction("/​var/​log/​blocked.log"))

Troubleshooting

Debug Commands

-- Enable verbose logging
setVerbose(true)
setVerboseHealthChecks(true)

-- Check server status
showServers()
getServer(0):getDrops()
getServer(0):getLatencyAvg()

-- Check cache performance
getPool(""):getCache():printStats()

-- View TLS errors
showTLSErrorCounters()

-- Traffic analysis
grepq("problem.domain.com", 100)
topQueries(20)
topSlowResponses(20)

Common Issues

IssueDiagnosisSolution
Server marked downshowServers() - check healthcheckVerify backend reachable, check checkName
High latencygetServer(N):getLatencyAvg()Add more backends, enable caching
Cache missesgetCache():printStats()Increase cache size, check minTTL
DoH not workingshowTLSErrorCounters()Verify certificates, check SNI
Rate limitingshowDynBlocks()Adjust thresholds, add exclusions

Resources

More DevOps & CI/CD skills

Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.

6K 472.6K
View

Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.

6K 472.6K
View

Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.

1.5K 454.3K
View
azure-kubernetes logo
DevOps & CI/CD

azure-kubernetes

Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.

1.5K 447.1K
View

Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.

92.7K 354.9K
View
just-scrape logo
DevOps & CI/CD

just-scrape

Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.

69 245K
View

Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.

462 159.7K
View

Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.

462 159.1K
View
deploy-to-vercel logo
DevOps & CI/CD

deploy-to-vercel

Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".

31.9K 146.6K
View
programmatic-seo logo
DevOps & CI/CD

programmatic-seo

Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.

53.3K 140.1K
View

Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.

63 123.5K
View

Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".

31.9K 116.1K
View

Coding & apps AI tools

Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View
Imagica logo
Coding & apps

Imagica

Build a no-code AI app in minutes.

Freemium
View
E
Coding & apps

Emergent.sh

An IDE for code migration from legacy to modern frameworks through coding agents.

Freemium
View
Wonder Dynamics logo
Coding & apps

Wonder Dynamics

Automate CGI animation in live-action scenes

Paid
View
M
Coding & apps

Mixo

Launch a website in seconds with AI.

Paid
View
AI Code Convert logo
Coding & apps

AI Code Convert

Streamline Your Coding Experience with AI Code Helper

Free
View