Behind the page is a large drawing, made of text characters, of a night sky: a ringed planet with a small moon, then a spiral galaxy and a black hole as the page scrolls, over faint constellations and twinkling stars.

AlfarelSandriano Subektiansyah

Software engineering student

I build fast, well-tested tools and backends in Rust, Go and TypeScript.

About

I build tools and backend services, and I measure them before I call them fast.

I study Software Engineering at Sepuluh Nopember Institute of Technology in Surabaya. I write most of my own projects in Rust, from a terminal editor for Typst to a mahjong stats site on Cloudflare Workers, and I use Go and Python in team work. I also teach: I have run labs on object-oriented programming, software design and Git. I am looking for a software engineering internship.

Based in
Surabaya, Indonesia
Looking for
Software engineering internship
Learning
Constraint programming and distributed systems

Projects

  • A terminal editor for Typst documents with a live preview that never blocks typing.

    Rust, Ratatui, Typst, Criterion

    Screenshot goes here

    Role
    Sole developer
    Built with
    Rust, Ratatui, Typst, Criterion

    Problem

    Writing Typst in the terminal meant switching to another window or a browser to see the result. Running the compiler on every change also made typing stutter.

    Solution

    I built an editor with the Typst compiler inside it. It compiles in the background and draws the rendered pages right in the terminal.

    Technical challenges

    • Recompiling on every edit without ever blocking input
    • Drawing rendered pages in terminals with different image support
    • Keeping the preview and the cursor position in sync

    Engineering decisions

    • Embed the Typst compiler instead of calling the typst executable
    • Split the code into crates for the document, compiler, renderer and interface
    • Cache rendered pages and only redraw the ones that changed
    • Benchmark every core operation with Criterion before tuning it

    What I learned

    That a benchmark suite changes how you work. Once I could see the render step was the slow part, one cache gave a bigger win than any other change.

    Read the case study

  • Tracks riichi mahjong stats from Tenhou game logs, for single games and whole careers.

    Rust, Cloudflare Workers, Cloudflare D1, Svelte, TypeScript

    Screenshot goes here

    Role
    Sole developer
    Built with
    Rust, Cloudflare Workers, Cloudflare D1, Svelte, TypeScript

    Problem

    Tenhou shows little more than placements after a game. I wanted to see my win rate, deal-ins and hand values over many games.

    Solution

    I built a site that fetches Tenhou game logs, parses every hand, and stores the results. It shows stats for a single game and for a player's whole career.

    Technical challenges

    • Parsing Tenhou's game log format hand by hand
    • Fetching logs politely so Tenhou never gets bursts of requests
    • Turning raw hands into stats like deal-in rates and yaku counts

    Engineering decisions

    • Keep the parser and stats in a pure Rust crate, apart from the API
    • Run the API as a Rust Worker with D1 for storage
    • Queue log fetches in a Durable Object, at least one second apart
    • Generate the TypeScript API types from the Rust types

    What I learned

    How to split a project so the hard part, the log parser and stats, can be tested on its own without a server or database.

    Read the case study

  • A tiny stack-based esoteric language in Rust, where every command is spelled with f, u and a.

    Rust

    Screenshot goes here

    Role
    Sole developer
    Built with
    Rust

    Problem

    I wanted to learn how interpreters work from the inside. A small, silly language was the easiest way to try it end to end.

    Solution

    I designed a stack language with thirteen commands, including loops and input, and wrote its interpreter in Rust. It runs as a command-line tool or as a library.

    Technical challenges

    • Matching loop starts and ends before the program runs
    • Reporting bad programs clearly instead of crashing

    Engineering decisions

    • Validate the program and precompute loop jumps at parse time
    • Read and write through standard I/O traits so callers can pass files or buffers

    What I learned

    That doing the work once at parse time, like finding loop jumps, keeps the interpreter loop short and simple.

    Read the case study

  • A Discord bot for a school server that helps new members introduce themselves and get class roles.

    Rust, Serenity, Discord API

    Screenshot goes here

    Role
    Sole developer
    Built with
    Rust, Serenity, Discord API

    Problem

    New members joined the school's Discord server without saying who they were. Moderators also had to change everyone's class role by hand each school year.

    Solution

    I rewrote the server's bot in Rust with slash commands. Members introduce themselves through a command or a form, and a class command updates roles.

    Technical challenges

    • Handling both slash commands and modal forms from the same bot
    • Formatting names in introductions consistently

    Engineering decisions

    • Rust with Serenity for a small, reliable bot
    • One module per command so new commands are easy to add

    What I learned

    How Discord's interactions work, and how to keep a bot simple enough that others can add commands.

  • A shared library where Informatics students upload, sort and read study notes and PDFs.

    Rust, Axum, PostgreSQL, Cloudflare R2, Next.js, TypeScript

    Screenshot goes here

    Role
    Sole developer
    Built with
    Rust, Axum, PostgreSQL, Cloudflare R2, Next.js, TypeScript

    Problem

    Study notes and past materials were spread across chats and personal drives. Students had no single place to find them by course or topic.

    Solution

    I built a site where signed-in students upload notes in Markdown or as PDFs, sorted into categories. Anyone signed in can filter, read and download them.

    Technical challenges

    • Uploading large PDFs without passing them through the API server
    • Supporting both email and Google sign-in
    • Paging and filtering resources by category

    Engineering decisions

    • Presigned URLs so the browser uploads PDFs straight to R2
    • A Rust Axum API with SQLx and PostgreSQL
    • Argon2 password hashes and JWT sessions

    What I learned

    How presigned uploads keep large files off the API server, and what that changes about validating them.

  • An event ticketing API in Rust, built to practice Clean Architecture and domain-driven design.

    Rust, Rocket, PostgreSQL, SQLx, Docker, OpenAPI

    Screenshot goes here

    Role
    Developer in a team of two
    Built with
    Rust, Rocket, PostgreSQL, SQLx, Docker, OpenAPI

    Problem

    Our Software Construction course gave us a ticketing case study with 20 user stories. The point was to show Clean Architecture and domain-driven design, not just a working API.

    Solution

    We split the system into domain, application, infrastructure and API crates. Every user story became a command or query handler behind a REST endpoint.

    Technical challenges

    • Keeping business rules in the domain, free of database code
    • Updating several aggregates in one transaction
    • Modeling booking, payment, check-in and refund states without gaps

    Engineering decisions

    • One crate per layer, so dependencies can only point inward
    • Payment, refunds and notifications behind ports with simulated adapters
    • Domain events for every important change, such as BookingPaid

    What I learned

    That ports and adapters pay off quickly: we could test the payment and refund rules long before any real payment service existed.

    Read the case study

  • A four-node demo of the PBFT consensus algorithm over QUIC, written to learn how it works.

    Rust, Tokio, QUIC, rustls

    Screenshot goes here

    Role
    Sole developer
    Built with
    Rust, Tokio, QUIC, rustls

    Problem

    I had read about Practical Byzantine Fault Tolerance, but the papers did not make it click. I wanted to see the message rounds happen between real processes.

    Solution

    I wrote a small PBFT network in Rust: four replica nodes and a client. The nodes talk over QUIC with TLS certificates and sign their messages.

    Technical challenges

    • Getting four nodes to connect to each other reliably at startup
    • Following the pre-prepare, prepare and commit rounds correctly
    • Generating keys and certificates for every node

    Engineering decisions

    • QUIC with quinn and rustls for encrypted links between nodes
    • Compact binary messages with postcard
    • A separate client binary that sends requests to the replicas

    What I learned

    How quorums let a network agree even when one node lies, and how much of a consensus protocol is really just bookkeeping.

    Read the case study

Case study

Skills

Languages

  • Rust
  • Go
  • TypeScript
  • Python
  • C#

Frameworks

  • Ratatui
  • Svelte
  • Tailwind CSS
  • Gin
  • FastAPI

Databases and cloud

  • PostgreSQL
  • Cloudflare D1
  • Cloudflare R2

Tools

  • Git
  • Docker
  • Postman

Operating systems

  • Arch Linux
  • NixOS
  • Linux Mint
  • Windows 11

Spoken languages

  • Indonesian (native)
  • English (intermediate)
  • Japanese (conversational)

Experience

  1. Sep 2026 – now

    Software engineer, Faculty Timetabling System

    ELECTICS, Sepuluh Nopember Institute of Technology

    • Built a timetabling engine in Python and OR-Tools that creates schedules and checks them on its own against every hard rule.
    • Designed a three-pass CP-SAT optimizer that uses fewer rooms, honors weighted lecturer preferences and shrinks gaps, and still returns a valid schedule after timeouts or solver failures.
  2. Aug 2024 – now

    Bachelor of Engineering, Software Engineering

    Sepuluh Nopember Institute of Technology

    • Holding a 3.79 GPA.
    • Took courses in object-oriented programming, data structures and algorithms, computer networks, operating systems and software development.
  3. Feb 2026 – Aug 2026

    Member

    LABSE, Laboratory of Software Engineering at ITS

    • Led hands-on Git training for 30 students, covering branching, merging and team workflows.
    • Gave orientation sessions on the lab's programs to 250+ first-year Informatics students.
    • Refactored and maintained the lab's website, keeping its code clean and its content current.
  4. Apr 2026 – Jun 2026

    Backend developer, Siklusin

    Joint project with Coca-Cola Europacific Partners

    • Built the backend for a marketplace where Indonesian sellers trade recycled goods and recyclable materials.
    • Designed the system and built 30+ REST endpoints across 7 services in Go.
    • Fixed location matching by reconciling mismatched map data between OpenStreetMap and a delivery API.
  5. Feb 2026 – Jun 2026

    Teaching assistant, Software Design

    Sepuluh Nopember Institute of Technology

    • Taught lectures and labs on design patterns, UML and object-oriented design to 50 students, turning theory into coding exercises.
    • Reviewed code and design documents with written feedback that pushed students toward clean, maintainable designs.
  6. Feb 2026 – Jun 2026

    Teaching assistant, Object-Oriented Programming

    Sepuluh Nopember Institute of Technology

    • Mentored 50 students on object-oriented programming through labs and one-on-one debugging help.
    • Debugged student code live, teaching them to isolate a problem step by step instead of patching symptoms.

Contact

Open to software engineering internships.

LinkedInGitHub

The form needs JavaScript. Email me instead.