Boostr is a companion tool for Layr.
In a nutshell, Boostr takes care of everything you need to build and deploy a Layr app so you can focus on what really matters — your app's code.
Here are the main features provided by Boostr:
- App templates so you can bootstrap an app with a single command
- Fully managed local development environment:
- Automatic frontend build and refresh
- Automatic backend build and restart
- Local development database (limited to MongoDB for now)
- Configuration management:
- Environment variables with inheritance and cross-service references
- Multiple stages (e.g.,
'development'
,'staging'
, and'production'
) - Public and private configurations
- Database migrations (limited to MongoDB for now)
- Serverless deployment with a single command (limited to AWS for now)
- You use a Mac with a recent version of macOS. Everything should work fine on Linux, but we haven't tested it yet. It may work on Windows, but we haven't tested it and don't plan to provide support for now.
- You have Node.js v16 or newer installed.
npm install --global boostr
Note: Installing an NPM package globally is usually not recommended. But it's not a problem in this case because each app managed by Boostr uses a local Boostr package which is automatically installed. So the global Boostr package can be seen as a shortcut to the local Boostr packages installed in your apps, and, therefore, you can have different apps using different versions of Boostr.
Boostr provides an initialize
command to bootstrap an app from a template.
For example, you can bootstrap a Layr web app using TypeScript with the following commands:
mkdir my-app
cd my-app
boostr initialize @boostr/web-app-ts
Then, you can open the my-app
directory in your favorite IDE to explore the initial codebase.
Note: You can use any IDE you want, but if you use Visual Studio Code, you can profit from the VS Code configuration included in the supported app templates. Otherwise, you may have to set up your IDE to get a suitable configuration.
Check out the initialize
command for details.
You can start your app in development mode with the following command:
boostr start
In the case of a web app, the terminal should output something like this:
[database] MongoDB server started at mongodb://localhost:18160/
[backend] Build succeeded (bundle size: 2.06MB)
[backend] Component HTTP server started at http://localhost:18159/
[frontend] Build succeeded (bundle size: 1.34MB)
[frontend] Single-page application server started at http://localhost:18158/
Notes:
- The TCP ports used for each local development URL were randomly set when the
initialize
command was executed to create your app in the previous section. So, it's normal if they are different for your app.- Don't be freaked out by the size of the generated bundles in development mode. When you deploy your apps, the generated bundles are a lot smaller.
The last line in the terminal output should include an URL you can open in a browser to display your app.
Check out the start
command for details.
First, make sure that your frontend and backend Boostr configuration files (frontend/boostr.config.mjs
and backend/boostr.config.mjs
) specify the URLs you want to use for your app.
So, if you just created a web app with the initialize
command, replace all the occurrences of 'example.com'
with your domain name (e.g., 'awesome.app'
) or subdomain name (e.g., 'project1.awesome.app'
).
Then, run the following command to deploy your app to production:
boostr deploy --production
Check out the deploy
command for details.
A Layr app managed by Boostr is usually composed of different services, and each service is associated with a configuration file named boostr.config.mjs
.
For example, a typical web app comprises the following directories and files:
boostr.config.mjs
: Application service configuration file (also called "root configuration file").frontend
:boostr.config.mjs
: Web-frontend service configuration file.
backend
:boostr.config.mjs
: Backend service configuration file.
database
:boostr.config.mjs
: Database service configuration file.
Note: The name of the directories (e.g.,
frontend
,backend
,database
) are specified in the root configuration file, so they can be anything you want.
Any configuration file is a JavaScript ESM module exporting a function (as default
export) which should return a plain object representing the configuration.
Here's an example of a simple root configuration file:
export default () => ({
type: 'application',
services: {
frontend: './frontend',
backend: './backend',
database: './database'
}
});
The type
property specifies a string representing the type of the service and is required for each configuration file. In the case of a root configuration file, the value of type
should be 'application
'.
The services
property specifies an object allowing to match the name of the services used by the app with the path of the directories containing these services.
The application service (also called "root service") is represented by a configuration file that specifies all the services used by your app and some general properties such as environment and stages.
Here's an example of an application service configuration file:
// boostr.config.mjs
export default () => ({
type: 'application',
services: {
frontend: './frontend',
backend: './backend',
database: './database'
},
environment: {
APPLICATION_NAME: 'Layr App',
APPLICATION_DESCRIPTION: 'A Layr app managed by Boostr.'
},
stages: {
staging: {
environment: {
NODE_ENV: 'production'
}
},
production: {
environment: {
NODE_ENV: 'production'
}
}
}
});
The object returned by the exported function contains the following properties:
type
: Specifies the type of service, which should always be'application'
in the case of an application service.services
:frontend
: Specifies the directory's path (./frontend
) of a web-frontend service simply named'frontend'
.backend
: Specifies the directory's path (./backend
) of a backend service incidentally named'backend'
.database
: Specifies the directory's path (./database
) of a database service incidentally named'database'
.
environment
: An object allowing you to define some global environment variables.stages
:
A web-frontend service is represented by a configuration file that specifies some properties related to the nature of a web frontend and some general properties, such as environment, stages, and dependsOn.
Here's an example of a web-frontend service configuration file:
// frontend/boostr.config.mjs
export default ({services}) => ({
type: 'web-frontend',
dependsOn: 'backend',
environment: {
FRONTEND_URL: services.frontend.url,
BACKEND_URL: services.backend.url
},
rootComponent: './src/index.ts',
html: {
language: 'en',
head: {
title: services.frontend.environment.APPLICATION_NAME,
metas: [
{
name: 'description',
content: services.frontend.environment.APPLICATION_DESCRIPTION
},
{charset: 'utf-8'},
{name: 'viewport', content: 'width=device-width, initial-scale=1'},
{'http-equiv': 'x-ua-compatible', 'content': 'ie=edge'}
],
links: [
{
rel: 'icon',
href: '/boostr-favicon-3NjLR7w1Mu8UAIqq05vVG3.immutable.png'
}
]
}
},
stages: {
development: {
url: 'http://localhost:10742/',
platform: 'local'
},
staging: {
url: 'https://staging.example.com/',
platform: 'aws',
aws: {
region: 'us-east-1',
cloudFront: {
priceClass: 'PriceClass_100'
}
}
},
production: {
url: 'https://example.com/',
platform: 'aws',
aws: {
region: 'us-east-1',
cloudFront: {
priceClass: 'PriceClass_100'
}
}
}
}
});
The object returned by the exported function contains the following properties:
type
: Specifies the type of service, which should always be'web-frontend'
in the case of a web-frontend service.dependsOn
: Specifies that the'frontend'
service depends on the'backend'
service. See "Service Dependencies" for details.environment
: An object allowing you to define some environment variables specific to the'frontend'
service. Note that'FRONTEND_URL'
and'BACKEND_URL'
are determined according to some service properties fetched from theservices
parameter of the configuration function. See "Service Property References" for a detailed explanation.rootComponent
: Specifies the file's path implementing the root Layr component of your web frontend.html
: An object allowing you to customize theindex.html
file automatically generated by Boostr. See "Autogeneratedindex.html
File" for details.stages
:development
: An object allowing you to define some properties when the'development'
stage is used.- We define the
url
property so you can access the web frontend locally (see "Local Development URLs" for details). - We set the value of the
platform
property to'local'
to indicate that Boostr should manage a local frontend server.
- We define the
staging
andproduction
: An object allowing you to define some properties when the'staging'
or'production'
stage is used.- We set the value of the
url
property to an URL where Boostr can deploy the web frontend (see "Deployment URLs" for details). - We set the value of the
platform
property to'aws'
to indicate that Boostr should use AWS as a deployment target. - Optionally, we can specify an
aws
object to customize the AWS configuration (see "Web-Frontend AWS Configuration" for details).
- We set the value of the
In the codebase of a Layr web app managed by Boostr, you will not see any index.html
file because this file is autogenerated.
We made this choice so that Boostr could abstract away the execution environment (e.g., browser, React Native, or Electron) in which the app runs.
So, your app should be mainly composed of configuration files and Layr components.
However, in most cases, it is necessary to customize the index.html
file so your web app can have, for example, a title and a favicon.
As seen in the above example, you can do so by setting the html
property in your web-frontend service configuration file.
The html
property should be an object composed of the following properties:
language
: A string specifying your web app's language (e.g.,'en'
). When theindex.html
file is autogenerated, this property determines the value of thelang
attribute of the<html>
tag (e.g.,<html lang="en">
).head
:title
: A string specifying your web app's title (e.g.,'My Awesome App'
). When theindex.html
file is autogenerated, this property determines the content of the<title>
tag in the<head>
section (e.g.,<title>My Awesome App</title>
).metas
: An array of objects specifying the attributes of some<meta>
tags to include in the<head>
section of the autogeneratedindex.html
file. See an example of use in the above example.links
: An array of objects specifying the attributes of some<link>
tags to include in the<head>
section of the autogeneratedindex.html
file. See an example of use in the above example.style
: A string specifying the content of a<style>
tag to include in the<head>
section of the autogeneratedindex.html
file. You can see an example of use in the web-frontend service configuration file of the Layr website.scripts
: An array of objects specifying the attributes of some<script>
tags to include in the<head>
section of the autogeneratedindex.html
file. You can see an example of use in the web-frontend service configuration file of the Layr website.
body
:scripts
: An array of objects specifying the attributes of some<script>
tags to include in the<body>
section of the autogeneratedindex.html
file.
You can customize the AWS configuration of a web frontend by specifying an object containing the following properties:
region
: Specifies the AWS region (e.g.,'us-east-1'
) where the web frontend is deployed.profile
: Specifies an AWS configuration profile (e.g.,'my-company'
) used to get your AWS credentials. If not specified, your default AWS configuration profile is used.accessKeyId
: Allows you to specify your AWS Access Key ID when theprofile
property is not used, or you don't have a default AWS configuration profile.secretAccessKey
: Allows you to specify your AWS Secret Access Key when theprofile
property is not used, or you don't have a default AWS configuration profile.cloudFront
:priceClass
: Specifies the Amazon CloudFront price class to use (default:'PriceClass_100'
).
A backend service is represented by a configuration file that specifies some properties related to the nature of a backend and some general properties, such as environment, stages, and dependsOn.
Here's an example of a backend service configuration file:
// backend/boostr.config.mjs
export default ({services}) => ({
type: 'backend',
dependsOn: 'database',
environment: {
FRONTEND_URL: services.frontend.url,
BACKEND_URL: services.backend.url,
DATABASE_URL: services.database.url
},
rootComponent: './src/index.ts',
stages: {
development: {
url: 'http://localhost:10743/',
platform: 'local'
},
staging: {
url: 'https://staging.backend.example.com/',
platform: 'aws',
aws: {
region: 'us-east-1',
lambda: {
memorySize: 1024
}
}
},
production: {
url: 'https://backend.example.com/',
platform: 'aws',
aws: {
region: 'us-east-1',
lambda: {
memorySize: 1024
}
}
}
}
});
The object returned by the exported function contains the following properties:
type
: Specifies the type of service, which should always be'backend'
in the case of a backend service.dependsOn
: Specifies that the'backend'
service depends on the'database'
service. See "Service Dependencies" for details.environment
: An object allowing you to define some environment variables specific to the'backend'
service. Note that'FRONTEND_URL'
,'BACKEND_URL'
, and'DATABASE_URL'
are determined according to some service properties fetched from theservices
parameter of the configuration function. See "Service Property References" for a detailed explanation.rootComponent
: Specifies the file's path implementing the root Layr component of your backend.stages
:development
: An object allowing you to define some properties when the'development'
stage is used.- We define the
url
property so the frontend can access the backend locally (see "Local Development URLs" for details). - We set the value of the
platform
property to'local'
to indicate that Boostr should manage a local backend server.
- We define the
staging
andproduction
: An object allowing you to define some properties when the'staging'
or'production'
stage is used.- We set the value of the
url
property to an URL where Boostr can deploy the backend (see "Deployment URLs" for details). - We set the value of the
platform
property to'aws'
to indicate that Boostr should use AWS as a deployment target. - Optionally, we can specify an
aws
object to customize the AWS configuration (see "Backend AWS Configuration" below for details).
- We set the value of the
You can customize the AWS configuration of a backend by specifying an object containing the following properties:
region
: Specifies the AWS region (e.g.,'us-east-1'
) where the backend is deployed.profile
: Specifies an AWS configuration profile (e.g.,'my-company'
) used to get your AWS credentials. If not specified, your default AWS configuration profile is used.accessKeyId
: Allows you to specify your AWS Access Key ID when theprofile
property is not used, or you don't have a default AWS configuration profile.secretAccessKey
: Allows you to specify your AWS Secret Access Key when theprofile
property is not used, or you don't have a default AWS configuration profile.lambda
:runtime
: Specifies the AWS Lambda runtime to use (default:'nodejs16.x'
).executionRole
: Specifies the IAM role used when the Lambda function is executed. If not specified, an automatically created role (named'boostr-backend-lambda-role-v2'
) will be used, allowing Amazon CloudWatch Logs management and Lambda function invocation.memorySize
: Specifies the amount of memory (in megabytes) available to the Lambda function at runtime (default:128
).timeout
: Specifies the maximum time (in seconds) that the Lambda function can run (default:10
).reservedConcurrentExecutions
: Specifies the number of concurrent executions reserved for the Lambda function (default:0
).
A database service is represented by a configuration file that specifies some properties related to the nature of a database and some general properties, such as stages.
Here's an example of a database service configuration file:
// database/boostr.config.mjs
export default () => ({
type: 'database',
stages: {
development: {
url: 'mongodb://localhost:10744/dev',
platform: 'local'
}
}
});
The object returned by the exported function contains the following properties:
type
: Specifies the type of service, which should always be'database'
in the case of a database service.stages
:development
: An object allowing you to define some properties when the'development'
stage is used.- We define the
url
property so the backend can access the database locally (see "Local Development URLs" for details). - We set the value of the
platform
property to'local'
to indicate that Boostr should manage a local database server.
- We define the
You may wonder where are the URLs of the staging and production databases. Well, the problem is that we cannot put these URLs in database/boostr.config.mjs
because they may contain sensitive information, such as access credentials.
Thankfully, we can add a private configuration file to solve the issue:
// database/boostr.config.private.mjs
export default () => ({
stages: {
staging: {
url: 'mongodb+srv://user:pass@clusterNane.mongodb.net/exampleStaging?retryWrites=true&w=majority'
},
production: {
url: 'mongodb+srv://user:pass@clusterNane.mongodb.net/exampleProduction?retryWrites=true&w=majority'
}
}
});
Using the environment
object property, you can define environment variables in any configuration file.
For example, here's how you would define an APPLICATION_NAME
environment variable in the root configuration:
// boostr.config.mjs
export default () => ({
// ...
environment: {
APPLICATION_NAME: 'Layr App'
}
// ...
});
Ahd here's how you would define an APPLICATION_DESCRIPTION
environment variable in a web-frontend service configuration:
// frontend/boostr.config.mjs
export default () => ({
// ...
environment: {
APPLICATION_DESCRIPTION: 'A Layr app managed by Boostr.'
}
// ...
});
And finally, here's how you would define a DATABASE_URL
environment variable in a backend service configuration:
// backend/boostr.config.mjs
export default ({services}) => ({
// ...
environment: {
DATABASE_URL: services.database.url
}
// ...
});
Note that the value of 'DATABASE_URL'
is determined according to a 'database'
service property fetched from the services
parameter of the configuration function. See "Service Property References" for a detailed explanation.
The environment variables defined in the root configuration are global, and therefore, they are accessible from all the services of your app.
So, in the examples above, the web-frontend service has access to APPLICATION_NAME
in addition to APPLICATION_DESCRIPTION
, and the backend service has access to APPLICATION_NAME
in addition to DATABASE_URL
.
You can access environment variables from your app's code via the process.env
object.
For example, here's how you would get the value of APPLICATION_NAME
from your frontend code:
// frontend/src/components/application.jsx
// ...
class Application extends Base {
@view() static HeaderView() {
return <h1>{process.env.APPLICATION_NAME}</h1>;
}
}
And here's how you would get the value of DATABASE_URL
from your backend code:
// backend/src/index.ts
// ...
const store = new MongoDBStore(process.env.DATABASE_URL);
Environment variables are also accessible when you run commands, such as test
, eval
, or repl
.
For example, if you run the following command:
boostr backend eval process.env.APPLICATION_NAME
The terminal should output something like this:
[database] MongoDB server started at mongodb://localhost:14128/
[backend] Build succeeded (bundle size: 2.06MB)
[backend] Evaluating code...
[backend] Result:
[backend] "Layr App"
[database] MongoDB server stopped
Generally, a Layr app managed by Boostr uses several stages, allowing you to define (or redefine) some configuration properties according to each stage.
For example, a typical app has the following stages:
'development'
: A stage used when you run your app in development mode on your local machine.'staging'
: A stage used when you deploy your app to your staging hosting environment.'production'
: A stage used when you deploy your app to production.
Note: You can define as many stages as you want and name them according to your preferences. However, if you use unconventional stage names, you won't be able to use a shorthand option, such as
--staging
or--production
, to select a stage.
Using the stages
property, you can define stages in any configuration file.
The stages
property should be an object composed of:
- Keys that represent the name of your stages.
- Values that allow you to define (or redefine) any configuration property according to each stage.
Here's an example of a root configuration file using the stages
property to change the value of the global APPLICATION_NAME
environment variable for the 'development'
and 'staging'
stages:
// boostr.config.mjs
export default () => ({
// ...
environment: {
APPLICATION_NAME: 'Layr App',
APPLICATION_DESCRIPTION: 'A Layr app managed by Boostr.'
},
stages: {
development: {
environment: {
APPLICATION_NAME: 'Layr App (development)'
}
},
staging: {
environment: {
APPLICATION_NAME: 'Layr App (staging)'
}
}
}
});
Note that in the example above:
- Since
APPLICATION_NAME
is not specified in a'production
' stage, its value will be'Layr App'
when the app is deployed to the'production'
stage. - Since
APPLICATION_DESCRIPTION
is not specified in any stage, its value will always be'A Layr app managed by Boostr.'
.
When you run a Boostr command, you can use the --stage
option to select a stage.
Alternatively, you can use one of the following shorthand options:
--development
: A shorthand for--stage=development
.--staging
: A shorthand for--stage=staging
.--production
: A shorthand for--stage=production
.
Note: The default stage is
'development'
, which will be used if you don't explicitly select another stage.
Examples:
# Starts the app while using the 'development' stage
boostr start --stage=development
# Since 'development' is the default stage, the following is equivalent
boostr start
# Deploys the app while using the 'production' stage
boostr deploy --stage=production
# Does the same thing by using the shorthand option
boostr deploy --production
Using the dependsOn
property, you can specify dependencies between the services of your Layr app.
So, for example, you can specify that a web-frontend service depends on a backend service, which itself depends on a database service.
When you start your app with the start
command, Boostr analyses the dependencies between your services and ensures that each dependency starts before each dependent.
So, in the example above, the services will start in the following order:
- Database service
- Backend service
- Web-frontend service
The same logic applies to other commands, such as the deploy
command.
Here's an example showing how to specify a dependency between a web-frontend service and a backend service:
// frontend/boostr.config.mjs
export default () => ({
type: 'web-frontend',
dependsOn: 'backend'
// ...
});
And here's an example showing how to specify a dependency between a backend service and a database service:
// backend/boostr.config.mjs
export default () => ({
type: 'backend',
dependsOn: 'database'
// ...
});
Using the services
parameter of a configuration function, the services of your Layr app can reference each other.
This feature allows you to configure your app in a way that is 100% DRY.
For example, let's take some configuration files:
// boostr.config.mjs
export default () => ({
type: 'application',
services: {
frontend: './frontend',
backend: './backend'
}
});
// frontend/boostr.config.mjs
export default ({services}) => ({
type: 'web-frontend',
environment: {
BACKEND_URL: services.backend.url
},
// ...
stages: {
development: {
url: 'http://localhost:10742/',
platform: 'local'
}
}
});
// backend/boostr.config.mjs
export default ({services}) => ({
type: 'backend',
environment: {
FRONTEND_URL: services.frontend.url
},
// ...
stages: {
development: {
url: 'http://localhost:10743/',
platform: 'local'
}
}
});
In the web-frontend service, the value of the 'BACKEND_URL'
environment variable is fetched from the backend service (incidentally named 'backend'
in the root configuration), which is accessible thanks to the services
parameter of the configuration function.
You can see the same mechanism used in the backend service. The value of the 'FRONTEND_URL'
environment variable is fetched from the web-frontend service (simply named 'frontend'
in the root configuration).
Note that a service can even reference itself. For example, if, for some reason, you need a web-frontend service to be aware of its own URL through an environment variable, you can do so with the following configuration file:
// frontend/boostr.config.mjs
export default ({services}) => ({
type: 'web-frontend',
environment: {
FRONTEND_URL: services.frontend.url
},
// ...
stages: {
development: {
url: 'http://localhost:10742/',
platform: 'local'
}
}
});
A local development URL looks like 'http://localhost:10742/'
for a web-frontend or backend service and 'mongodb://localhost:10744/dev'
for a database service.
When you initialize an app with the initialize
command, the TCP ports (e.g., 10742
) used for each service are randomly set. It ensures that you will never encounter port conflicts while working on several apps simultaneously.
A deployment URL (e.g., 'https://example.com/'
or 'https://staging.example.com/'
) indicates where Boostr should deploy a service. Note that currently, the DNS associated with your base domain names (e.g., 'example.com'
) must be managed by Amazon Route 53.
Most apps use secrets that must remain private and never be included in your Git repositories (even if these repositories are private).
Your app configuration files should be included in your Git repositories and, therefore, cannot contain any secrets.
So how could you configure secrets without exposing them?
Boostr supports private configuration files that work like any configuration file but should be named boostr.config.private.mjs
and stored next to your public configuration files named boostr.config.mjs
.
Private configuration files are automatically excluded from Git thanks to a line (e.g., *.private.*
) in a .gitignore
file at the root of your repositories.
When Boostr evaluates your app's configuration, it reads both public and private configuration files and deeply merges them.
Note: Private configurations precede public configurations, so a property found in a private configuration can override a property of the same name found in a public configuration.
Let's say your app implements an authentication mechanism using a JWT library to sign and verify users' access tokens.
JWT relies on a secret that should be accessible from your backend. So, in your backend directory, you could specify this secret in a private configuration file next to your public configuration file.
Here's what your public configuration file would look like:
// backend/boostr.config.mjs
export default () => ({
type: 'backend',
environment: {
EMAIL_ADDRESS: 'hello@example.com'
},
// ...
stages: {
development: {
// ...
},
production: {
// ...
}
}
});
And here's what your private configuration file would look like:
// backend/boostr.config.private.mjs
export default () => ({
stages: {
development: {
environment: {
JWT_SECRET: '26d9c27e799aba1b047ec16450a51418...'
}
},
production: {
environment: {
JWT_SECRET: '537df3079d44e066bf0195433863ec34...'
}
}
}
});
You can get some help from the Boostr CLI by using the --help
option.
Get some general help by running the following:
boostr --help
Get some help for a global command (e.g., start
) by running the following:
boostr start --help
Get some help for a specific service (e.g., 'frontend'
) by running the following:
boostr frontend --help
Get some help for a command of a specific service (e.g., the import
command of the 'database'
service) by running the following:
boostr database import --help
The global commands are available for all services, including the root of your app, which is represented by a service of type 'application'
.
Alias: boostr init
Initializes your app within the current directory from the specified template.
The <template>
argument specifies the template to use, which should be a published npm package.
Currently, two templates are available:
@boostr/web-app-js
for initializing a web app using JavaScript@boostr/web-app-ts
for initializing a web app using TypeScript
We will publish more templates in the future. For example, some React Native or Electron app templates should soon be available.
A template is simply an npm package. So, the community can publish any new template, and if needed, you can create some templates for your personal use.
In addition to the global options, the initialize
command accepts the following option:
--name
: Specifies the name of your app (defaults to the name of the current directory).
# Creates a web app named `my-app` using TypeScript
mkdir my-app
cd my-app
boostr initialize @boostr/web-app-ts
You can check out the outcome of the above example in the Boostr repository.
# Creates a web app named `my-awesome-app` using JavaScript
mkdir my-directory
cd my-directory
boostr init @boostr/web-app-js --name=my-awesome-app
You can check out the outcome of the above example in the Boostr repository.
Installs all the npm dependencies used in your app (or a specified service).
Under the hood, this command runs npm install
.
See the global options.
# Installs all the npm dependencies used in your app
boostr install
# Installs all the npm dependencies used in the 'frontend' service
boostr frontend install
Updates all the npm dependencies used in your app (or a specified service).
Under the hood, this command runs npm update
.
See the global options.
# Updates all the npm dependencies used in your app (including Boostr itself)
boostr update
# Updates all the npm dependencies used in the 'backend' service
boostr backend update
Checks the TypeScript code of your app (or a specified service).
Under the hood, this command runs tsc --noEmit
.
See the global options.
# Checks the TypeScript code of your app
boostr check
# Checks the TypeScript code of the 'backend' service
boostr backend check
Builds runnable artifacts from the source code of your app (or a specified service).
Note: This command is automatically executed when you run some other commands, such as
start
ordeploy
. So, unless you want to check out the built runnable artifacts for debugging purposes, you should not have to use thebuild
command explicitly.
See the global options.
# Builds runnable artifacts from the source code of your app
boostr build
# Builds runnable artifacts from the source code of the 'frontend' service
boostr frontend build
# Builds runnable artifacts from the source code of your app while using
# the 'production' stage configuration
boostr build --production
Tests all the services of your app (or a specified service) in development mode.
Under the hood, this command runs npm test
.
See the global options.
# Tests all the services of your app
boostr test
# Tests the 'backend' service
boostr backend test
Starts your app (or a specified service) in development mode.
See the global options.
# Starts all the services of your app in development mode
boostr start
# Starts the 'backend' service (and the services it depends on)
# in development mode
boostr backend start
Migrates one or more databases used by your app.
Note: Database migrations are limited to MongoDB for now.
See the global options.
# Migrates all the databases used by your app in the 'development' environment
boostr migrate
# Migrates all the databases used by your app in the 'staging' environment
boostr migrate --staging
# Migrates the 'customers' database in the 'development' environment
boostr customers migrate
Deploys your app (or a specified service) to a specific stage.
In addition to the global options, the deploy
command accepts the following option:
--skip
: Skips the specified service when deploying. Note that you can repeat this option several times to skip multiple services.
- Currently, only AWS is supported as a deployment target.
- The DNS associated with your base domain name must be managed by Amazon Route 53.
- The first deployment may take a while because several AWS services have to be set up, but subsequent deployments should be much faster.
- Boostr manages the deployment of the web-frontend and backend services, but the database services are not. So, you will have to set up the databases by yourself on some cloud services, such as MongoDB Atlas or Amazon DocumentDB.
# Deploys all the services of your app to the 'staging' stage
boostr deploy --stage=staging
# Does the same thing by using the shorthand option
boostr deploy --staging
# Deploys all the services of your app to the 'production' stage
boostr deploy --stage=production
# Does the same thing by using the shorthand option
boostr deploy --production
# Deploys the 'backend' service (and the services it depends on)
# to the 'production' stage
boostr backend deploy --production
# Deploys all the services of your app to the 'staging' stage while
# skipping the 'legacyBackend' service
boostr deploy --staging --skip=legacyBackend
Displays the root (or a specified service) configuration.
Note: The displayed configuration considers all the property references and resolves them according to a specific stage (
'development'
by default).
See the global options.
# Displays the root configuration for the 'development' environment
boostr config
# Displays the configuration of the 'frontend' service for the 'development' environment
boostr frontend config
# Displays the configuration of the 'backend' service for the 'production' environment
boostr backend config --production
Executes any shell command in the root directory of your app (or in the directory of a specified service).
Note: The environment variables specified in your configuration are accessible from the executed shell command.
See the global options.
# Executes `npx prettier --check .` in the root directory of your app
boostr exec -- npx prettier --check .
# Executes `npm install lodash` in the directory of the 'backend' service
boostr backend exec -- npm install lodash
# Executes `npm version patch --no-git-tag-version` in the directory of
# the 'frontend' service
boostr frontend exec -- npm version patch --no-git-tag-version
# Executes `npm run myscript` in the directory of the 'backend' service
# with the environment variables of the 'production' stage
boostr backend exec --stage=production -- npm run myscript
The web-frontend commands are available for all services of type 'web-frontend'
.
Freezes all the files in your web-frontend service's public
directory.
Freezing a file means that the file is renamed to match the pattern <name>-<hash>.immutable.<extension>
where <name>
is the original file name without its extension, <hash>
is a hash generated from the contents of the file, and <extension>
is the original file extension.
For example, if you have a file named favicon.png
in the public
directory of your 'frontend'
service, running boostr frontend freeze
will rename the favicon.png
file to something like favicon-3NjLR7w1Mu8UAIqq05vVG3.immutable.png
.
When a browser loads a frozen file, it can permanently store it in its cache thanks to a Cache-Control
header automatically added when your frontend is deployed.
Note: It is not an issue to run the
freeze
command several times because the command is clever enough to ignore the files that have already been frozen.
The backend commands are available for all services of type 'backend'
.
Evaluates the specified JavaScript code with your backend service root component exposed globally and outputs the result in the terminal.
See the global options.
If you run the following command with a web app that has just been initialized from the @boostr/web-app-ts
template:
boostr backend eval "Application.isHealthy()"
The terminal should output something like this:
[database] MongoDB server started at mongodb://localhost:10744/
[backend] Build succeeded (bundle size: 2.06MB)
[backend] Evaluating code...
[backend] Result:
[backend] true
[database] MongoDB server stopped
Starts a Node.js REPL with your backend root component exposed globally.
See the global options.
If you run the following command with a web app that has just been initialized from the @boostr/web-app-ts
template:
boostr backend repl
Then, you should be able to execute the following JavaScript code inside the REPL:
await Application.isHealthy();
And the REPL should output the following result:
true
The following options are available for most commands:
--stage
: Selects a stage. See "Stages" for details.--development
: A shorthand for--stage=development
.--staging
: A shorthand for--stage=staging
.--production
: A shorthand for--stage=production
.--help
,-h
: Displays inline help. See "Inline Help" for details.--version
,-v
: Displays the current Boostr version.
Contributions are welcome.
Before contributing please read the code of conduct and search the issue tracker to find out if your issue has already been discussed before.
To contribute, fork this repository, commit your changes, and send a pull request.
MIT