diff --git a/packages/xarc-create-app/template/_tsconfig.json b/packages/xarc-create-app/template/_tsconfig.json
new file mode 100644
index 000000000..30df9b797
--- /dev/null
+++ b/packages/xarc-create-app/template/_tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "outDir": "lib",
+ "lib": [
+ "es2018"
+ ],
+ "allowJs": true,
+ "module": "CommonJS",
+ "esModuleInterop": true,
+ "target": "ES2018",
+ "preserveConstEnums": true,
+ "sourceMap": true,
+ "declaration": true,
+ "types": [
+ "node"
+ ],
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "alwaysStrict": true,
+ "strictFunctionTypes": true
+ },
+ "include": [
+ "src"
+ ]
+}
\ No newline at end of file
diff --git a/packages/xarc-create-app/template/src/demo1/subapp-demo1.ts b/packages/xarc-create-app/template/src/demo1/subapp-demo1.ts
new file mode 100644
index 000000000..dc2308279
--- /dev/null
+++ b/packages/xarc-create-app/template/src/demo1/subapp-demo1.ts
@@ -0,0 +1,21 @@
+import { React, loadSubApp } from "subapp-react";
+
+const Demo1 = props => {
+ return (
+
+
subapp demo1
+ props: {JSON.stringify(props)}
+
+ Electrode Docs
+
+
+ );
+};
+
+export default loadSubApp({
+ Component: Demo1,
+ name: "Demo1",
+ prepare: () => {
+ return { data: "hello from demo1" };
+ }
+});
diff --git a/packages/xarc-create-app/template/src/demo2/reducers.ts b/packages/xarc-create-app/template/src/demo2/reducers.ts
new file mode 100644
index 000000000..e9c284a95
--- /dev/null
+++ b/packages/xarc-create-app/template/src/demo2/reducers.ts
@@ -0,0 +1,15 @@
+const number = (store = { value: 0 }, action) => {
+ if (action.type === "INC_NUMBER") {
+ return {
+ value: store.value + 1
+ };
+ } else if (action.type === "DEC_NUMBER") {
+ return {
+ value: store.value - 1
+ };
+ }
+
+ return store;
+};
+
+export default number;
diff --git a/packages/xarc-create-app/template/src/demo2/subapp-demo2.ts b/packages/xarc-create-app/template/src/demo2/subapp-demo2.ts
new file mode 100644
index 000000000..0991107cc
--- /dev/null
+++ b/packages/xarc-create-app/template/src/demo2/subapp-demo2.ts
@@ -0,0 +1,51 @@
+import { React } from "subapp-react";
+import { connect } from "react-redux";
+import { reduxLoadSubApp } from "subapp-redux";
+import reduxReducers from "./reducers";
+
+const incNumber = () => {
+ return {
+ type: "INC_NUMBER"
+ };
+};
+
+const decNumber = () => {
+ return {
+ type: "DEC_NUMBER"
+ };
+};
+
+const Demo2 = props => {
+ const { value, dispatch } = props;
+
+ return (
+
+
+
subapp demo2
+ Redux State Demo:
+ {value}
+
+
+
© {new Date().getFullYear()} Your (Company) name here
+
+ );
+};
+
+const mapStateToProps = state => state;
+
+export default reduxLoadSubApp({
+ Component: connect(mapStateToProps, dispatch => ({ dispatch }))(Demo2),
+ name: "Demo2",
+ reduxReducers,
+ prepare: ({ context, request }) => {
+ return Promise.resolve({ value: 999 });
+ }
+});
diff --git a/packages/xarc-create-app/template/src/home/subapp-home.ts b/packages/xarc-create-app/template/src/home/subapp-home.ts
new file mode 100644
index 000000000..847894748
--- /dev/null
+++ b/packages/xarc-create-app/template/src/home/subapp-home.ts
@@ -0,0 +1,15 @@
+import { React, loadSubApp } from "subapp-react";
+import electrodePng from "../../static/electrode.png";
+
+const Home = () => {
+ return (
+
+ );
+};
+
+export default loadSubApp({ Component: Home, name: "Home" });
diff --git a/packages/xarc-create-app/template/src/routes.ts b/packages/xarc-create-app/template/src/routes.ts
new file mode 100644
index 000000000..9f8360461
--- /dev/null
+++ b/packages/xarc-create-app/template/src/routes.ts
@@ -0,0 +1,8 @@
+export const favicon = "static/favicon.png";
+
+export default {
+ "/": {
+ pageTitle: "Welcome to Electrode",
+ subApps: ["./home", "./demo1", "./demo2"]
+ }
+};
diff --git a/packages/xarc-create-app/template/src/server/config.ts b/packages/xarc-create-app/template/src/server/config.ts
new file mode 100644
index 000000000..e282ff163
--- /dev/null
+++ b/packages/xarc-create-app/template/src/server/config.ts
@@ -0,0 +1,44 @@
+"use strict";
+
+/**
+ * A simple configuration to setup fastify to serve routes for the
+ * Electrode X webapp.
+ *
+ * To support config composition base on environment, checkout these:
+ *
+ * 1. https://www.npmjs.com/package/electrode-confippet
+ * 2. https://www.npmjs.com/package/config
+ *
+ */
+exports.config = {
+ connection: {
+ host: process.env.HOST || "localhost",
+ // Allow Electrode X to control app's listening port during dev
+ // to serve both static assets and app under a unified proxy port
+ port: parseInt(process.env.APP_SERVER_PORT || process.env.PORT || "3000")
+ },
+ plugins: {
+ /**
+ * Register the dev support plugin
+ */
+ "@xarc/app-dev": {
+ priority: -1,
+ enable: process.env.WEBPACK_DEV === "true"
+ },
+ /**
+ * Register the server routes plugin for the app
+ */
+ "subapp-server": {
+ options: {
+ cdn: {
+ /**
+ * Enable CDN in production mode. To try this locally, do:
+ * 1. npm run build
+ * 2. NODE_ENV=production clap mock-cloud
+ */
+ enable: process.env.NODE_ENV === "production"
+ }
+ }
+ }
+ }
+};
diff --git a/packages/xarc-create-app/template/src/server/index.ts b/packages/xarc-create-app/template/src/server/index.ts
new file mode 100644
index 000000000..a597e6de8
--- /dev/null
+++ b/packages/xarc-create-app/template/src/server/index.ts
@@ -0,0 +1,12 @@
+"use strict";
+
+const support = require("@xarc/app/support");
+const electrodeServer = require("@xarc/fastify-server");
+const { config } = require("./config");
+
+async function start() {
+ await support.load();
+ await electrodeServer(config);
+}
+
+start();
diff --git a/packages/xarc-create-app/template/xclap.ts b/packages/xarc-create-app/template/xclap.ts
new file mode 100644
index 000000000..30af49bb9
--- /dev/null
+++ b/packages/xarc-create-app/template/xclap.ts
@@ -0,0 +1,26 @@
+import { loadXarcDevTasks } from "@xarc/app-dev/lib/dev-tasks";
+import * as xrun from "@xarc/run";
+
+xrun.updateEnv(
+ {
+ /*
+ * Configure local development with http://localhost:3000
+ */
+ HOST: "localhost",
+ PORT: 3000,
+ /*
+ * Set app's node server to listen at port 3100 so the proxy can listen at 3000
+ * and forward request to the app.
+ */
+ APP_SERVER_PORT: 3100,
+ /*
+ * Enable Electrode's built-in webpack dev server and reverse proxy for development
+ */
+ WEBPACK_DEV_MIDDLEWARE: true
+ },
+ {
+ // do not override any env flag already set in process.env
+ override: false,
+ }
+);
+loadXarcDevTasks(null, {});
\ No newline at end of file