Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Publish local files to virtually any remote endpoint (AWS S3, etc.)

npm version Travis Status Coverage Status MIT licensed

poosh cli screenshot

Short Example

Install poosh CLI and S3 plugin:

> npm install -g poosh-cli poosh-plugin-s3

Create a .poosh.json5 file at the root of your project:

  plugins : ["s3"],
  baseDir : "./deploy",
  remote  : "",

  each: [{
    headers   : { "cache-control": { cacheable: "public" } }
  }, {
    match     : "**/*.{html,css,js}",
    gzip      : true,
    headers   : { "cache-control": { maxAge: "48 hours" } }
  }, {
    match     : "**/*.{jpg,png,gif,ico}",
    gzip      : false,
    headers   : { "cache-control": { maxAge: "1 year" } }
  }, {
    match     : "**/*.html",
    priority  : -1

You can now upload:

> poosh

Or sync if you want to delete remote files that has been locally removed:

> poosh sync

Main Features

Glob Selection | GZIP | HTTP Headers | Upload Ordering | Automatic Redirection | Cache | Simulation

Poosh allow you to upload and sync local files to virtually any remote destination.

Glob Selection

Using the match option, local files that needs to be uploaded can be selected and configured with a glob string:

  each: [{
    match: "**/*.html"

or an array of patterns

  each: [{
    match: ["*.*", "!*.txt"]

Some supported glob features are:

Feature Example
Brace Expansion "foo/bar-{1..5}.html", "one/{two,three}/four.html"
Typical glob patterns "**/*", "a/b/*.js"
Logical OR "foo/bar/(abc|xyz).js"
Regex character classes "foo/bar/baz-[1-5].jpg"
POSIX bracket expressions "**/[[:alpha:][:digit:]]/"
extglobs "**/+(x|y)", "!(a|b)", etc.


Using the GZIP option, files can be compressed at remote destination:

  each: [{
    match : "**/*.html",
    gzip  : true

content-encoding HTTP header will accordingly be set to gzip.

HTTP Headers

Using the headers option, HTTP headers can be configured for each files:

  each: [{
    match : "**/*.html",
    headers: {
      "cache-control": {
        maxAge      : "60 days",
        cacheable   : "public",
        noTransform : true,
        immutable   : true
      "content-disposition" : "attachment; filename=\"foo.html\"",
      "content-encoding"    : "utf-8",
      "content-language"    : "en-us",
      "content-length"      : 500,
      "content-md5"         : "Q2hlY2sgSW50ZWdyaXR5IQ==",
      "content-type"        : "text/html; charset=utf-8",
      "expires"             : "0",
      "location"            : ""

content-encoding, content-length and content-type HTTP headers are automatically generated by default.

Upload Ordering

Sometimes some files must be uploaded before other ones to avoid inconsistency. The priority option can be used to order uploads:

  each: [{
    match     : "**/*.html",
    priority  : -1

Greatest values are uploaded first.

Automatic Redirection

Using the header-location-from-html plugin, the location HTTP header can be automatically generated from a file HTML http-equiv meta tag.

First install the plugin:

> npm install -g poosh-plugin-header-location-from-html

And then use it in your configuration file:

  plugins: ["header-location-from-html"],
  each: [{
    match     : "**/*.html",
    headers   : { location: { fromContent: true } }


When local files are processed, a .poosh.cache file is generated next to the .poosh.json5 configuration file.

Consecutive runs of poosh will use this file to avoid unnecessary remote requests.

Poosh CLI can be used with the --force options to bypass cache lookup:

> poosh --force cache

The cache file is written after each individual file processing (using the great NeDB append-only format). Cache file stores 3 separate hash keys for each processed local file:

  • File content hash key
  • HTTP headers hash key
  • Remote options hash key

This is useful to poosh to detect distinctive local changes in either file content, HTTP headers and remote options.


Using the CLI --dry-run or --read-only options, no changes will be maid while output still showing potential changes:

> poosh --dry-run


> poosh sync --dry-run


Option Default Description
plugins [] List of plugins to load and use. A single plugin is designed by it's package name (with or without it's poosh-plugin- prefix).
baseDir null The base directory of local files. This path can either be absolute or relative (to the configuration file).
remote null The remote client or a key/value map of remote clients to use for processing files. See your remote plugin documentation for more information (e.g. S3 Plugin).
concurrency 3 File processing concurrency.
each [] List of items used to select and process local files. Available options are described in the each section.
ignore [] List of glob strings identifying files to totally ignore (prevent files to be created, updated or deleted).


All "each" items are applied to files in order. Same options are overridden by the last one.

Option Default Description
match null A glob string used to match files. If not specified, other options are applied to all files without marking them "to be processed".
priority null Greatest values are processed first.
gzip false If true, will gzip the file in remote destination.
headers [] List of headers options.
remote "default" The key of the remote client to use. Or an object with an id key and some other ones that will define specific remote client options.


Options used to control file's HTTP headers.

Option Default Description
cache-control null String or object. The object can be a combination of the following keys:
  • maxAge: A number (of seconds) or a string that will be parsed by ms. For example "60 days", "2.5 hours", "1 year", "35 minutes", etc.
  • cacheable: Can be one of the following values: null, "public", "private", "no-cache".
  • noTransform: Boolean.
All those keys are null by default.
content-disposition null String.
content-encoding null Content encoding header is automatically generated at runtime. Using this option will force the header to the specified value.
content-language null String.
content-length null Number. Content length header is automatically generated at runtime. Using this option will force the header to the specified value.
content-md5 null String.
content-type null Content type header is automatically generated at runtime. Using this option will force the header to the specified value.
expires null String.
location null String.


🌎 Publish local files to virtually any remote endpoint (e.g. AWS S3)