diff --git a/umka.html.markdown b/umka.html.markdown
new file mode 100644
index 00000000..1b76bbc4
--- /dev/null
+++ b/umka.html.markdown
@@ -0,0 +1,178 @@
+---
+language: Umka
+filename: learnumka.um
+contributors:
+ - ["Marek Maškarinec", "https://mrms.cz"]
+---
+
+Umka is a statically typed scripting language meant to be embedded into
+programs, useful in cases like mod support in games, or user scripting.
+
+It draws inspiration from Pascal and Go.
+
+```
+// Single line comment
+/* Multi line comments
+ they can't be nested */
+
+// The import statement can import other files
+import (
+ "std.um" // the standard library - included in the interpreter
+ "map.um" // hashmaps
+ "utf8.um" // utf8 encoding and decoding
+)
+
+// Functions are declared with the fn keyword. They have to be declared before
+// usage. To combat this, umka allows function prototypes.
+// The main function serves as an entry point when running the file.
+// Included files can contain main too.
+fn main() {
+ // printf works the same as in c. It is builtin, so you don't need to
+ // import any file to use it.
+ printf("Hello world!\n")
+
+ // Variables have to be declared before use. There are multiple ways to do so.
+ var x: int = 3 // full declaration
+ var y: uint32 // you can ignore the value
+ var z = 5 // you can also ignore the type
+ a := 6 // umka also allows short declarations like in go
+
+ y = 4 // variable assignment
+
+ // there aren't doubles or floats in umka. They are called real and
+ // real32 instead.
+ var pi: real = 3.14
+
+ // if statements
+ if pi == 3.14 {
+ printf("Close enough.\n")
+ } else if pi == 3 {
+ printf("You should learn about real values.\n")
+ } else {
+ printf("You live in a strange world.\n")
+ }
+
+ // Umka has only one key word for loops.
+ // Traditional while loop:
+ for z > 0 {
+ printf("%d\n", z)
+ z--
+ }
+
+ // for loop:
+ for i:=0; i < y; i++ {
+ printf("%d\n", i)
+ }
+
+ // the string type is called str
+ var name: str = "John"
+ // string concatenation
+ name += " Doe"
+
+ // Umka has two types of arrays - fixed and dynamic. Fixed have fixed size,
+ // are stored on the stack and passed by value. Dynamic are the opposite.
+ // You can append and slice them, they are stored on the heap and passed by
+ // reference.
+
+ // A fixed array
+ names := [4]str{"Jonathan", "Joseph", "Jotaro", "Josuke"}
+
+ // Making a dynamic array is done by just removing the number
+ dynNames := []str{"Jonathan", "Joseph", "Jotaro", "Josuke"}
+ // It is also possible to create a zero initialized dynamic array of a given
+ // length. The length doesn't have to be a constant.
+ arr := make([]int, 23)
+
+ // Dynamic arrays can be appended. Be aware, that the array is always newly
+ // allocated, and the old elements are copied. This makes the process of
+ // appending very slow.
+ dynNames = append(dynNames, "Giorno")
+
+ // You can also delete an element from an array.
+ dynNames = delete(dynNames, 3) // => { "Jonathan", "Joseph", "Jotaro", "Giorno" }
+
+ // You can also slice them. Start inclusive, end exclusive.
+ part1 := slice(dynNames, 0, 2)
+ // You can ommit the ending index and it will be replaced by the length
+ // of the array.
+ part2 := slice(dynNames, 2)
+
+ // You can iterate over a string, array and a dynamic array
+ // using the "for in" loop.
+ for index, value in dynNames {
+ printf("%d: %s\n", index, value)
+ }
+
+ // Umka supports pointers. You can make a pointer type by writing a ^ before
+ // the base type.
+ var xPointer: ^int
+
+ // Values are referenced using an &
+ xPointer = &x
+
+ // You can dereference them by writing a ^ after the value
+ printf("%s: %d\n", repr(xPointer), xPointer^) // => 0xaddress : 3
+}
+
+// Functions are declared using the fn keyword. Parameters are in parenthesis,
+// the return type follows after a :. Functions don't have to take parameters,
+// or return any values.
+fn learnFunctions(a, b: int, c: real): real {
+ return a + b * c
+}
+
+// Functions can return multiple values.
+fn learnMultiple(): (int, int) {
+ x, y := getPosition()
+
+ x *= 2
+ y *= 2
+
+ return x, y
+}
+
+// The type keywords allows type aliases
+type Number int
+
+// You can use it to define your own structure types.
+type Vector2 = struct {
+ x, y: real
+}
+
+fn newVector2(x, y: real): Vector2 {
+ // Structure literals
+ return Vector2{ x, y }
+}
+
+// You can define methods on any type from the current module.
+fn (v: ^Vector2) multiply(x: real) {
+ v.x *= x
+ v.y *= x
+}
+
+// An interface is a form of duck typing in Umka. It defines a set of methods,
+// that must be implemented by a type to implement said interface.
+type Representable = interface {
+ toStr(): str
+}
+
+// Vector2 now implements Representable
+fn (v: ^Vector2) toStr(): str {
+ return "[ " + repr(v.x) + repr(v.y) + "]"
+}
+
+// This function takes a variadic number of Representable values
+fn println(args ...Representable) {
+ // variadic arguments act like an array inside a function
+ for arg in args {
+ printf("%s", repr(arg))
+ }
+
+ printf("\n")
+}
+```
+
+## Further reading
+
+You can learn more details in the [documentation](https://github.com/vtereshkov/umka-lang/tree/master/doc).
+If you want to read real Umka code, read some of the [examples](https://github.com/vtereshkov/umka-lang/tree/master/examples).