Using configuration

Pass an object or use Config directly.

CommonJS · representative configuration
const {Server}=require('node-http-server');

const server=new Server({
    host:'127.0.0.1',
    port:8080,
    root:'./public',
    server:{
        noCache:false,
        allowDotfiles:false,
        compression:true,
        maxRequestBodyBytes:1048576
    }
});

server.deploy();
APIBehavior
new Server(values?)Creates an instance with an isolated Config.
server.deploy(values?)Merges supplied values before deployment.
new Config(values?)Creates isolated configuration without deploying.
config.merge(values)Safely merges and returns the same Config instance.
Config.defaultsReturns a fresh copy of all defaults.
Config.mimeTypesReturns a fresh built-in MIME map.
CommonJS subpaths
const Config=require('node-http-server/config');
const mimeTypes=require('node-http-server/mime-types');
ESM subpaths
import Config from 'node-http-server/config';
import mimeTypes from 'node-http-server/mime-types';

Network, roots, and top-level state

Separate binding from Host routing.

KeyDefaultPurposePlayground
host'127.0.0.1'Address passed to listen().Location and host routing
port8080HTTP port; 0 requests an ephemeral port.Location and host routing
rootprocess.cwd()Default static root.Location and host routing
domain'0.0.0.0'Legacy primary Host check; not a bind address.Location and host routing
domains{}Additional hostname-to-root mappings.Additional domains JSON
verbosefalseSanitized operational console output.HTTP behavior
servertable belowStatic HTTP behavior and Node timeouts.HTTP behavior + Timeouts
httpsempty valuesCertificate paths and secure listener mode.HTTPS
contentTypebuilt-in mapMIME additions/overrides, or false.File types and restrictions
restrictedType{}Truthy extension keys return 403.File types and restrictions
errorsbuilt-in mapError headers and status bodies.Logging and errors
logfalseNDJSON destination or logging off.Logging and errors
logBodyfalseInclude UTF-8 body in request records.Logging and errors
logFunctionbuilt inCustom request-record writer.Module-only function stub
host versus domain: host chooses the network interface. domain and domains choose accepted Host values and static roots. A mismatch returns 421.
Virtual-host requirement: wildcard domain:'0.0.0.0' or domain:'*' selects the primary root before domains is consulted. Set a nonwildcard primary domain when using the map.
ESM · virtual host roots
new Server({
    root:'./www/default',
    domain:'example.test',
    domains:{
        'docs.example.test':'./www/docs',
        'app.example.test':'./www/app'
    }
}).deploy();

Static server behavior

The server object.

KeyDefaultPurpose
index'index.html'File used for directory requests. There is no directory listing when it is absent.
noCachetrueSends no-cache/no-store/must-revalidate directives. false omits them; it does not add a cache lifetime.
allowDotfilesfalseOnly literal true allows dot-prefixed path segments. The default returns 403 before lookup or SPA fallback.
compressionfalseNegotiates Brotli/gzip for accepted compressible static responses; ranges and manual serve() responses are not compressed.
compressionThreshold1024Minimum uncompressed bytes before compression is considered.
spaFallbackfalsetrue uses index; a string chooses another root-relative file.
timeout30000Socket inactivity timeout in milliseconds.
requestTimeout300000Whole-request timeout in milliseconds.
headersTimeout60000Request-header timeout in milliseconds.
keepAliveTimeout5000Keep-alive timeout in milliseconds.
maxRequestBodyBytesfalseMaximum request bytes; false/0 is unlimited.
SPA conditions: fallback applies only after an initial 404, for an extensionless path whose request accepts HTML or */*. Missing assets and non-HTML requests remain 404.
Dotfile opt-in: allowDotfiles:true exposes every dot-prefixed segment in the selected root, including /.git, /.env, and /.well-known. Use a dedicated audited root.

Limits and timeouts

Every disable value is explicit.

Settingfalse0Unit
server.timeoutDisabledDisabledmilliseconds
server.requestTimeoutDisabledDisabledmilliseconds
server.headersTimeoutDisabledDisabledmilliseconds
server.keepAliveTimeoutDisabledDisabledmilliseconds
server.maxRequestBodyBytesUnlimitedUnlimitedbytes
contentTypeAutomatic map removedInvalid map value
Programmatic null: false, null, and numeric 0 disable timeouts and the body cap through the module API. The CLI accepts false/off/0, not null.
Operational choice: disabled values are supported, not recommended as a universal default. Set finite limits for the traffic and proxy chain you actually operate.

File types and restrictions

Serve, reject, or use the binary fallback.

ConfigurationResult
No entry for extensionapplication/octet-stream.
contentType:{md:'text/markdown; charset=utf-8'}Adds or overrides that extension.
contentType:{secret:false}Filenames ending in .secret return 415 after path policy checks.
contentType:falseRemoves automatic mapping; served files use application/octet-stream.
restrictedType:{key:true}Filenames ending in .key return 403 after path policy checks.
JavaScript · MIME and extension controls
new Server({
    contentType:{
        md:'text/markdown; charset=utf-8',
        secret:false
    },
    restrictedType:{
        key:true,
        pem:true
    }
});

Extension keys do not include a dot. The built-in map is available through Config.mimeTypes or the node-http-server/mime-types package subpath. If an object is merged after contentType:false, the built-in defaults are restored first and then overlaid.

Error responses

Override headers or individual bodies.

KeyDefault / shapeUse
errors.headersContent-Type: text/plain; charset=utf-8, X-Content-Type-Options: nosniffHeaders applied to built-in error responses.
errors[400]'400 Bad Request'Malformed request.
errors[403|404|405]Status textDenied, missing, or unsupported method.
errors[413|415|416|421|500]Status textLimit/type/range/Host/internal failures.
JavaScript · custom error response
new Server({
    errors:{
        headers:{'Content-Type':'application/json'},
        404:'{"error":"not found"}'
    }
});

Logging

Append NDJSON or provide a writer.

KeyDefaultBehavior
logfalseFile path enables one JSON record per request line.
logBodyfalseAdds the UTF-8 request body when deliberately enabled.
logFunctionbuilt-in append writerReceives the record with this bound to Config; may return a Promise.

The built-in writer adds a timestamp without mutating its input and redacts common credential headers. Serialization/filesystem errors are captured. Protect log destinations and treat any stored request body as sensitive.

JavaScript · custom logger
new Server({
    log:true,
    logFunction(data){
        return sendRecordSomewhere(data);
    }
});

HTTPS

Supply key and certificate paths together.

KeyDefaultPurpose
https.ca''Optional CA certificate path.
https.privateKey''Private-key path.
https.certificate''Certificate path.
https.passphrasefalseOptional private-key passphrase.
https.port443HTTPS port.
https.onlyfalseSkip HTTP when HTTPS is configured.
ESM · HTTPS only
const server=new Server({
    host:'127.0.0.1',
    https:{
        privateKey:'/path/to/private.key',
        certificate:'/path/to/certificate.pem',
        port:8443,
        only:true
    }
});

server.deploy();
Certificates: repository fixture keys were removed. Generate fresh local certificates, keep private keys out of source control, and never use copied v8 fixture keys; they are public and untrusted.

Validation and merging

Invalid configuration fails before serving.

CheckFailure
Config is not a plain objectTypeError.
Nested map is not a plain objectTypeError naming the key.
__proto__, constructor, or prototypeRejected as unsafe.
Port not an integer in 0–65535Deployment throws.
Host emptyDeployment throws.
Root/domain root missing or not a directoryDeployment throws.
Negative timeout/limit/thresholdDeployment throws.
Only one of HTTPS key/certificate setDeployment throws.
https.only:true without key/certificateDeployment throws.

Merge precedence is defaults, then constructor values, then later deploy()/merge() overlays. Known nested records shallow-overlay and omitted earlier values persist. Instances, Config.defaults, Config.mimeTypes, and user maps do not share mutable nested state. Unknown safe top-level keys are accepted but ignored by the server.