Skip to projects

Devank Yadav

I solve a problem once, then write it down.

Penn State, Computational Data Science, December 2027. State College, PA.

I work Penn State's IT desk, about thirty student and faculty tickets a week. I spent a summer building factory-floor software in India.

I taught myself driver code no course asked of me, and I build things meant to run unwatched.

I started the largest developer community on campus from nothing and run it for seventy-plus members.

Projects

glanceOS

July 2026

Turns any browser-capable screen into a live dashboard that nobody has to log into, click, or remember to change.

Why it exists

Screens are everywhere, and almost all of them are either dark or showing something that wants attention. A spare monitor, the TV in a waiting room, an old tablet, a battery e-paper panel on a wall.

glanceOS makes them useful and quiet. A screen shows what was chosen for it and nothing else, and there is nothing to configure on the device itself: plug it in, join Wi-Fi, claim it with the code it puts on the glass, and everything after that happens in a web app.

How it works

One server process is the source of truth for devices, boards, and integration data. Screens are dumb glass. They subscribe over Server-Sent Events and render what they are sent, and they cache the last state they were given, so a Wi-Fi blip or a server restart never blanks a wall display. Battery e-paper devices cannot hold a connection open, so they poll instead and get back a pre-rendered 1-bit image of the same board, rendered from the same runtime rather than from a second implementation.

Boards are composed in a Notion-style studio: click anywhere and type, or drop in blocks from a palette of 221 types covering charts, clocks, lists, calendars, tickers, and big numbers. A block binds to one of 190 built-in integrations, to anything that can send a webhook, or to values typed in directly, and falls back to those typed values when a source is unreachable. There are 166 starter boards to begin from, and one board rotates through its own pages on a schedule, so a screen can run standup in the morning and sales in the afternoon unattended. The whole thing self-hosts as one container with a single SQLite file, the screen runtime is held under 32 KB so an old TV browser can run it, and no data leaves the machine.

How a board reaches a screen

  1. Integrations to Server
  2. Server to Rules engine
  3. Rules engine to Server: switch board, alert
  4. Server to SSE hub
  5. SSE hub to Screen runtime: push
  6. Server to E-paper: poll

The hard part

An alert is only worth having if it is right, and both ways of being wrong are expensive. A rule that fires on every blip teaches people to ignore the wall, and a rule tuned quiet enough to stop that will sit silent through a real incident. The first attempt at the quiet side was a per-rule cooldown, which is a rate limiter rather than an understanding: it stops the same alert repeating, but it cannot tell a five-second spike from a deploy queue that has genuinely been backed up for twenty minutes, and it holds back the second alert of a real incident exactly as readily as the second alert of a false one. What works is making the engine time-aware instead. A sustained node keeps a first-true timestamp per rule node, so a condition counts only once it has held continuously for N minutes. Edge comparators read the current sample against the previous one and fire on the transition tick alone, so crossing a threshold alerts once instead of every minute until someone fixes it. A stale sense stamps when a watched field last changed, which catches the failure nobody writes a rule for: a sensor that quietly stopped reporting and is therefore never out of range. Trends are judged over a chosen window from an hour to ninety days rather than against the last reading.

The constraint that made this awkward to build is that the evaluator has to stay pure and total. The same condition tree against the same context must always produce the same verdict, offline, reading no clock of its own. Duration is inherently stateful, so none of the history lives inside it. The tick layer resolves every sustained node once per pass, innermost first, and threads the verdicts back in as an argument, keyed by a node’s own content rather than its position in the tree, so two identical rules share one timer and rearranging a rule does not silently reset a condition that has been counting for nineteen minutes. That history re-baselines on restart, which is the honest cost: after a restart, a twenty-minute condition starts counting from zero. Past a few alerts in a ten-minute window the individual banners collapse into one summary instead of taking over the wall, and anything nobody acknowledges re-raises itself later, louder and on every channel the account can reach.

Stack

  • TypeScript
  • Node.js
  • SQLite
  • Server-Sent Events
  • Preact
  • Docker
  • Raspberry Pi
  • ESP32

Links

CarbonSight

September 2025, MLH Best Use of the Gemini API, PennApps XXVI

A four-person build at PennApps XXVI. Devank owned the React dashboard layer.

Sends each prompt to the smallest Gemini model that can still answer it, and shows a team the energy behind every answer.

Why it exists

A team running prompts through a model API sees a token bill and nothing about energy. Nobody can say which of yesterday’s calls needed the largest model and which would have been answered as well one tier down.

CarbonSight makes that choice before the call and reports it after. The router picks the tier, and the dashboard puts the estimate in front of the person who typed the prompt as well as the manager who pays for it.

How it works

A prompt reaches a semantic cache first. Gemini embeddings and cosine similarity look for a question close enough to one already answered, and a match returns the stored answer with no model call at all. On a miss the router reads an energy threshold and the quality tolerance the user set, picks Flash-Lite, Flash, or Pro, and allocates a thinking budget by how hard the task looks. The agent workflow runs on Google ADK behind a FastAPI backend.

Devank built the React layer above that. Every answer carries an efficiency badge, so the cost lands on the person who typed the prompt instead of in a monthly report; team leaderboards and org-wide analytics give managers the same numbers aggregated, and carbon-credit reports export out of them. Verified gains issue ERC-20 tokens and ERC-721 badges through OpenZeppelin contracts on Polygon, which puts the record of a saving somewhere other than the dashboard that claims it.

Request path

  1. Prompt to Semantic cache
  2. Semantic cache to Router: miss
  3. Router to Flash-Lite
  4. Router to Flash
  5. Router to Pro
  6. Flash-Lite to Dashboard
  7. Flash to Dashboard
  8. Pro to Dashboard
  9. Dashboard to Polygon: verified gains

The hard part

Nothing in a model API reports energy. There is no joules field and no per-call kWh, so the number the whole product rests on had to be derived from what the API does return: latency and token counts, mapped to an estimated kWh per model tier and from there to CO₂. That is an approximation, and it is worth saying so plainly rather than dressing it up. What makes it usable is that the same mapping runs over every call, so two prompts that differ in the dashboard differ in fact, and a leaderboard built on it puts people in the right order even if the absolute grams are wrong. Ordering is what a leaderboard actually needs, and consistency is what buys it. Carbon accounting is the claim the data would not support.

Stack

  • Google ADK
  • Gemini
  • FastAPI
  • React
  • Polygon
  • Supabase
  • Python
  • Node.js

Links

Built with Advita Shrivastava, Ira Pathak, and Aarav Raina.

iPad-to-Mac Drawing Tablet

June 2026

Turns an iPad and an Apple Pencil into a pressure-sensitive drawing tablet that any Mac application can use, over a USB cable.

Why it exists

A pressure-sensitive drawing tablet costs a few hundred dollars, and the iPad and the Pencil are already on the desk. Sidecar connects the two devices, but it mirrors a display: the iPad becomes a second screen, not an input device that the Mac’s own applications can read pressure from.

The missing piece is a driver. Something the operating system treats as a real tablet, so pressure arrives in whatever application is already open instead of inside a screen-sharing session.

How it works

An iPad app captures Apple Pencil input, including position, pressure, and tilt, and streams it to the Mac over the USB cable with Peertalk, which multiplexes a socket connection between an iOS device and a connected Mac. On the Mac, a DriverKit extension reads that stream and translates it into tablet events, so an application that already knows how to handle a graphics tablet sees one attached and does not need to know what is on the other end of the cable.

DriverKit is the constraint that shapes the rest. Drivers run in user space rather than in the kernel, are written in C++ against a deliberately narrow set of APIs, and require system extension entitlements before macOS will load them at all. Pressure passes through a curve-mapping stage on the way through, so the number the Pencil reports is not the number the driver hands to the system.

Event path

  1. Apple Pencil to iPad app
  2. iPad app to USB
  3. USB to DriverKit extension
  4. DriverKit extension to Any Mac app

The hard part

The difficulty was never moving bytes across the cable. It was correctness at the level of individual fields: a tablet event carries position and pressure in a particular range and a particular coordinate space, and every one of those has to agree with what the receiving application expects. Get a range or a space wrong and nothing fails loudly. Strokes still appear, roughly where the Pencil is, with roughly the weight it was pressed at, so the result looks plausible and feels wrong, which is a far harder thing to chase than an error. The narrow DriverKit surface makes it harder again, because there is not much room to inspect what the system does with an event once it has left the driver. And the pressure curve on top of that is a judgement rather than a lookup: a Pencil pressed lightly and a stylus pressed lightly on a dedicated tablet do not report the same number, so mapping between them means deciding what a light stroke should mean and then checking it by drawing, not by reading a log.

Stack

  • DriverKit
  • C++
  • Swift
  • Peertalk
  • USB
  • macOS
  • iPadOS

Zoodu

October 2024, Best RAG Chatbot, HackPSU Fall 2024

Answers a question about Penn State’s research computing clusters out of the ICDS User Guide rather than out of a model’s memory.

Why it exists

The ICDS User Guide covers Penn State’s research computing clusters from one end to the other: connecting, submitting jobs, handling data, using software. A researcher who opens it usually wants one line out of it. Which queue to submit to, which module to load, how much of a storage quota is left.

Reading a manual to find that line is the wrong shape of work for someone who is halfway through a job submission. A chatbot that locates the relevant part of the guide and answers from it hands back the line instead of the document.

How it works

The guide is stored as sections, each one with its title, its text, and the URL it came from. An incoming question is matched against those sections, the matching section is handed to the model as the material to answer from, and the reply is written out of that text rather than out of what the model already knows. A Flask backend does the matching and the model call, and the interface is a single page.

The hard part

Retrieval always returns something. The guide is a handful of long sections, and a match on any shared word means "how are you doing" lands on whichever section happens to contain the word "how", after which the model answers at length, and confidently, about submitting jobs. Off-topic questions fail in the same direction, and so does anything conversational. Tightening the match is the obvious fix and it trades one failure for the other, because a stricter bar starts refusing real questions phrased in words the guide does not use. What the work came down to was the decision in front of the retriever rather than the retrieval itself: sorting an incoming message into a question the guide can answer, small talk, or something the guide has nothing to say about, and making that last case say so plainly instead of guessing.

Stack

  • Python
  • Flask
  • SQL
  • HTML
  • CSS

Links

Skoda India Documentation System

Summer 2025

Built during a Software Development Internship at Taikisha Group, May to August 2025.

Scan the code on a machine part to pull up its manual, report the fault, and order the replacement without leaving the floor.

Why it exists

Maintenance documentation at the plant lived on paper. Finding the manual for an industrial part meant finding the binder that held it, and doing that on the floor, next to the machine, was the part that did not work.

Reporting a malfunction and ordering the replacement were their own processes on top of that, each with a person in the middle. The technician who found the problem was not the one who could move it forward.

How it works

Every part carries a QR code. Scanning it opens that part’s record on the floor: its manuals and product documents, and the actions available on it. From the same record a technician files a malfunction report and orders a replacement part, so the fault and the order stay attached to the part they came from instead of being re-entered somewhere else.

An order picks up a vendor quotation on its way through rather than being reconciled with one afterwards. Engineering and procurement use the same application under different roles, and user management for those roles is part of the application.

The hard part

The scanning was the easy half. The difficulty was that engineering, procurement, and vendors each see a different slice of the same order, and the flow has to stay one flow while the permissions diverge. A technician needs to file a fault and request a part; procurement needs the quotation and the vendor side of the same request; the vendor needs only what is being ordered. Building those as three separate screens would have been straightforward and would have quietly rebuilt the handoffs the paper process already had. Keeping it one flow meant the order stayed a single record from report to quotation, and the role decided what of it rendered and what could be changed, which is a harder thing to reason about than three screens because every state of the record has to be correct under every role at once.

Stack

  • React
  • QR scanning
  • Role-based access

Other builds

  • ESP32 water-tank automation Embedded automation for a water tank, running on an ESP32.
  • Lirra A storytelling companion for children, built at Cal Hacks 12.0. It detects emotion in a child’s speech and text, then generates a story around it, narrated in a cloned parent voice with comic-style art. Devpost
  • Tuk Tuk Campus carpooling, built at HackPSU Spring 2025. Students, faculty, and staff post and search rides inside a community where everyone is a verified member. Devpost

Experience

IT Support Technician, Penn State IT

March 2026 to Present, University Park, PA

Hardware, software, and network problems arrive from students and faculty across Windows, macOS, and the university systems. About thirty tickets a week.

The part that compounds is the writing. Recurring issues and their resolutions get documented, so a problem already solved once does not come back as an escalation, and the first response arrives sooner.

  • Troubleshoot hardware, software, and network issues for students and faculty across Windows, macOS, and university systems, resolving ~30 tickets weekly.
  • Document recurring issues and resolutions to reduce repeat escalations and shorten first-response time.

Software Development Intern, Taikisha Group

May 2025 to August 2025, India

The plant kept documentation for its industrial parts on paper. I built a React internal web application that replaced that workflow: every part carries a QR code, and scanning it opens that part’s manuals and product documents on the factory floor.

Reporting a malfunction and ordering the replacement happen in the same flow as the lookup, and an order picks up a vendor quotation on its way through. Engineering and procurement work in the same application under different roles, and managing those roles is part of it.

  • Built a React internal web application for Skoda India that digitized documentation management for industrial parts, replacing a paper-based maintenance workflow.
  • Implemented QR code scanning to retrieve manuals and product documents instantly on the factory floor, alongside malfunction reporting and replacement-part ordering in a single flow.
  • Integrated vendor quotation generation and built role-based user management for secure access across engineering and procurement teams.

Founder and President, Developers at Penn State

November 2024 to Present, University Park, PA

I started Developers at Penn State in November 2024 and still lead it. It is now the university’s largest developer community, with more than seventy active members.

The programming is technical workshops, coding competitions, and hackathons, arranged so that people learn by building something and by teaching whoever is sitting next to them.

  • Founded and lead Penn State’s largest developer community, growing it to 70+ active members.
  • Organize technical workshops, coding competitions, and hackathons that drive project-based learning and peer mentorship.

Education

Penn State, College of Engineering

B.S. Computational Data Science, expected December 2027

Skills

Languages: Python, TypeScript, JavaScript, C++, Java, SQL

Frameworks and tools: React, Node.js, Express, FastAPI, Docker, Git, MySQL, MongoDB, Supabase, SQLite

AI and data: Retrieval-Augmented Generation, Embeddings and semantic search, Google ADK, Gemini API, REST API design

Systems: DriverKit, Server-Sent Events, ESP32, Raspberry Pi, Time-series alerting