Skip to content

Latest commit

 

History

History
403 lines (314 loc) · 17.6 KB

README.md

File metadata and controls

403 lines (314 loc) · 17.6 KB

elide: verb. to omit (a sound or syllable) when speaking. to join together; to merge.


Build codecov Reliability Rating Security Rating Maintainability Rating FOSSA Status

Java 19 GraalVM Kotlin Kotlin/JS. IR supported ECMA

Latest version: 1.0-v3-alpha3-b7


Elide is a Kotlin/Multiplatform meta-framework for rapid, cross-platform application development. Write once in Kotlin and deploy everywhere: your server, the browser, and native app targets.

Using Elide as a runtime

First and foremost, Elide is a runtime. The runtime is still in alpha. You can try it like with:

curl -sSL --tlsv1.2 "dl.elide.dev/cli/install.sh" | bash -s -

Or you can try it via NPM:

npx @elide-dev/elide@alpha --help

Using Elide as a library

Elide is available on Maven Central. To use it, pick the package you want to use (typically server) and add it via Gradle or Maven:

Gradle

dependencies {
    implementation 'dev.elide:elide-server:1.0-v3-alpha3-b7'
}
dependencies {
    implementation("dev.elide:elide-server:1.0-v3-alpha3-b7")
}

Maven

<dependency>
    <groupId>dev.elide</groupId>
    <artifactId>elide-server</artifactId>
    <version>1.0-v3-alpha3-b7</version>
</dependency>

Distinguishing features

  • Full-stack development. Share code across platforms with Kotlin Multiplatform. Quickly develop performant UIs in Kotlin, TypeScript, or JavaScript, and execute them server-side (streaming SSR) or client-side (SPA).

  • Countless ways to run. Use SSR (server rendering), CSR (client rendering), or an isomorphic approach. Compile your app to HTML via SSG. Run your app on a JVM, Node.js, JS runtime, or compile it to a native binary and run it without a runtime at all.

  • Pure Kotlin when you want it. Write your core application logic and models once, and share them across platforms transparently. Leverage Kotest for cross-platform, write-once-run-native testing. Enjoy first-class support for the full suite of KotlinX libraries, including serialization, atomicfu, coroutines and datetime.

  • TypeScript/JavaScript when you need it. Plug your Kotlin code into the JavaScript ecosystem with embedded guest VM support for ES2022.

  • Isomorphic SSR with React. Write your UI in React, using JavaScript, TypeScript, or Kotlin. Package it for serving via client-side rendering or hybrid isomorphic rendering directly from your Kotlin server.

  • Model-driven development. Write your models once, and use them everywhere, across platforms, without copying, without glue-code, and without DTOs. Via Protobuf and Kotlin data classes, the same Elide model is code-generated for use with your database, API, and UI.

  • Extreme performance. Enjoy fast development locally with Kotlin and Gradle, and insanely fast runtime performance thanks to GraalVM Native, Netty, and Micronaut. Deploy to bare metal, Docker scratch images, or JARs.

Code samples

A full suite of code samples demo various functionality. The samples are runnable locally or via pre-built Docker images. Click through to each one for a short tour and getting started guide.

"Blah blah blah, okay, show me some code." Certainly:

App.kt (for the server)

/** GET `/`: Controller for index page. */
@Controller class Index {
  // Serve an HTML page with isomorphic React SSR.
  @Get("/") fun index() = ssr {
    head {
      title { +"Hello, Elide!" }
      stylesheet("/styles/main.css")
      script("/scripts/ui.js", defer = true)
    }
    body {
      injectSSR()
    }
  }

  // Serve styles for the page.
  @Get("/styles/main.css") fun styles() = css {
    rule("body") {
      backgroundColor = Color("#bada55")
    }
    rule("strong") {
      fontFamily = "-apple-system, BlinkMacSystemFont, sans-serif"
    }
  }

  // Serve the built & embedded JavaScript.
  @Get("/scripts/ui.js") suspend fun js(request: HttpRequest<*>) = script(request) {
    module("scripts.ui")
  }
}

main.kt (for the browser)

// React props for a component
external interface HelloProps: Props {
  var name: String
}

// React component which says hello
val HelloApp = FC<HelloProps> { props ->
  div {
    strong {
      +props.name
    }
  }
}

// Entrypoint for the browser
fun main() {
  hydrateRoot(
    document.getElementById("root"),
    Fragment.create() {
      HelloApp {
        name = "Elide"
      }
    }
  )
}

That's it. That's the entire app. In fact, it's just the fullstack/react-ssr sample pasted into the README. What we get out of this is surprising:

  • Server: JVM or Native server (via GraalVM) that serves our root page, our CSS, and our JS
  • Client: Embedded JS VM that executes a Node copy of our React UI and splices it into the page for isomorphic rendering
  • For us (the developer):
    • Completely type-checked calls across platforms, with almost no boilerplate
    • Single build graph, with aggressive caching and tool support
    • Build & test virtualized on any platform
    • Ship & perform natively on any platform

What's going on here? Elide has helped us wire together code from Micronaut (that's where @Controller comes from), Kotlin/JS, GraalVM, and esbuild to make the above code make sense on both platforms. The React code builds for the browser and a pure server environment; both are embedded into the JAR and served through a thin runtime layer provided by the framework.

Why is this useful?

If you're participating in the React and Java ecosystems, this gives you a fantastic best-of-both-worlds runtime option: superb tooling support for React and Kotlin and an ideal serving and rendering mode, all handled for you.

You can do the same thing with these same tools in a custom codebase, but setting up the build environment for this kind of app is challenging and error-prone. Elide intentionally leverages existing frameworks with rich ecosystems and docs, instead of re-providing existing functionality so that you always have an escape hatch up to a more industrial toolset if you need it.

Trying it out

Note Elide is early. This guide will soon be usable without cloning the source.

There are currently two ways to try out Elide. You can build a sample from source, or run the pre-built Docker images. Native images are not yet available via Docker, but you can build and test them locally.

The react-ssr sample is recommended, because it demoes the broadest set of functionality currently available. Source code for each sample is in the samples/ directory. If you're going to build from source, make sure to see the Requirements to build section.

Run the helloworld sample via Docker (JVM):

docker run --rm -it -p 8080:8080 ghcr.io/elide-dev/samples-server-helloworld-jvm

Run the react-ssr sample via Docker (JVM):

docker run --rm -it -p 8080:8080 ghcr.io/elide-dev/samples-fullstack-react-ssr-jvm:latest

Run the react-ssr sample via Gradle (JVM):

git clone [email protected]:elide-dev/v3.git && cd v3
./gradlew :samples:fullstack:react-ssr:server:run

Run the react-ssr sample via Gradle (Native):

git clone [email protected]:elide-dev/v3.git && cd v3
./gradlew :samples:fullstack:react-ssr:server:runNative

Requirements to build

To build the JVM or JS samples in Kotlin, you will need JDK 11 or later. Zulu is a good option if you don't have a preferred JVM.

To build native code, you'll need a recent version of GraalVM. Make sure to install the native-image tool after initially downloading, which you can do with:

gu install native-image espresso
gu rebuild-images

Finally, you'll need a recent Node.js runtime if you want to build JS or frontend code. That's it!

To summarize:

  • For building via Gradle: JDK11+, any reasonable JVM should work.
  • For building native: GraalVM (consult compat table for version advice).
  • For building browser/embedded JS: Recent Node.js toolchain. 16.x+ is recommended.

Powered-by

Elide is modular. You can mix and match the following technologies in server, client, or hybrid/fullstack development scenarios:

  • Kotlin. Elide is written from the inside out with support for Kotlin/Multiplatform, including native platforms. Write once and use the same consistent code across server-side and client-side(s) platforms.

  • GraalVM. GraalVM is a JVM and toolchain from Oracle which includes modernized JIT support, cross-language polyglot development in JS, Ruby, Python, and LLVM, and the ability to build native binaries from JVM apps.

  • Micronaut. Micronaut is a new JVM-based framework for building server-side applications. Elide leverages Micronaut's dependency injection and AOP features, and transparently works with most add-ons.

  • React. React is a popular UI library written for browser and server environments. Elide leverages Kotlin/JS support for React for isomorphic UI rendering. CSR and SSR modes are supported natively.

  • Protobuf / gRPC. Elide leverages cross-platform serialization through KotlinX's protobuf module, and includes native support for gRPC Web without running a proxy.

  • Gradle. Early support for building multi-platform Kotlin applications via Gradle, including integrated support for Webpack-based frontend builds and esbuild-based embedded SSR builds.

  • esbuild. Elide leverages ESBuild when compiling and minifying JS code for the server or browser. ESBuild sports extremely fast build times, modern language support, and tunable minification/DCE.

Version compatibility

The following version matrix indicates tested support across tool and platform versions, including Java, Kotlin, GraalVM, Micronaut, and React.

Following this guide is recommended but optional. Depending on the style of development you're doing with Elide, you may not need some of these components:

Status Java Kotlin GraalVM Micronaut React Protobuf/gRPC
Status Java 19 1.8.20 22.3.x 3.9.x 18.x 3.21.11/1.51.0
Status Java 17 1.8.20 22.3.x 3.9.x 18.x 3.21.1/1.51.0
Status Java 11 1.7.22 22.3.x 3.5.x 18.x 3.20.1/1.46.0
Status Java 8-10 -- -- -- -- --

If you aren't using certain components on this list, for example, gRPC/Protobuf, you can ignore that column entirely.

Contributing

Elide is structured as a Gradle codebase, with additional support for Make and Node. Bazel is also coming soon. After cloning the project, you can run make help to get familiar with some standard local dev tasks.

  1. Clone the repo.
    git clone [email protected]:elide-dev/v3.git
    
  2. Install GraalVM. You can download CE here. Make sure to install the native-image, espresso, and js tools after initially downloading, which you can do with:
    gu install native-image js espresso
    gu rebuild-images
    
  3. Explore the Makefile. The Makefile is self-describing. Run make help to see what it can do for you:
Elide:
api-check                      Check API/ABI compatibility with current changes.
build                          Build the main library, and code-samples if SAMPLES=yes.
clean-docs                     Clean documentation targets.
clean-site                     Clean site targets.
clean                          Clean build outputs and caches.
cli-local                      Build the Elide command line tool and install it locally (into ~/bin, or LOCAL_CLI_INSTALL_DIR).
cli                            Build the Elide command-line tool (native target).
distclean                      DANGER: Clean and remove any persistent caches. Drops changes.
docs                           Generate docs for all library modules.
forceclean                     DANGER: Clean, distclean, and clear untracked files.
help                           Show this help text ('make help').
publish                        Publish a new version of all Elide packages.
relock-deps                    Update dependency locks and hashes across Yarn and Gradle.
reports                        Generate reports for tests, coverage, etc.
serve-docs                     Serve documentation locally.
serve-site                     Serve Elide site locally.
site                           Generate the static Elide website.
test                           Run the library testsuite, and code-sample tests if SAMPLES=yes.
update-deps                    Perform interactive dependency upgrades across Yarn and Gradle.
update-jdeps                   Interactively update Gradle dependencies.
update-jsdeps                  Interactively update Yarn dependencies.
  1. Take a look at the Makefile flags. The Makefile defines flags at the top of the source code:
# Flags that control this makefile, along with their defaults:
#
# DEBUG ?= no
# STRICT ?= yes
# RELEASE ?= no
# JVMDEBUG ?= no
# NATIVE ?= no
# CI ?= no
# DRY ?= no
# SCAN ?= no
# IGNORE_ERRORS ?= no
# RELOCK ?= no

When committing to Elide, make sure to follow the Conventional Commits standard. This helps us keep changelogs clean and obvious.

Reports

Licensing

Elide itself is licensed under MIT as of November 2022. Dependencies are scanned for license compatibility; the report is available via FOSSA:

FOSSA Status

Coverage

Code coverage is continuously reported to Codecov and SonarCloud:

Coverage grid