Have you ever been coding and then gotten into that flow state? You know where hours pass by , and it feels to you it's only ben a few minutes? Me too. One thing that really helps me get into that state is music. So I create my own music Lo-Fi server called compile and chill.
As a part of this project, I created three radio stations. Each station can generate a 16:9 scene with Amazon Bedrock, compose an instrumental loop with ElevenLabs, and turn an illustration into a six-second video through OpenRouter. Generated files live in private Amazon S3 storage and return to the browser through the Nuxt server.
You need the following tools for the complete build: Node.js 22.19 or newer. The locked Nuxt 4.5.2 release requires Node 22.19+, 24.11+, or 26+. npm 10 or newer. An AWS account and a configured AWS Command Line Interface (AWS CLI) profile. The AWS Serverless Application Model (AWS SAM) CLI for the private storage stack. Access to Stability AI Stable Image Ultra through Amazon Bedrock in us-west-2. An ElevenLabs API key for music generation. An OpenRouter API key for animated scenes.
The provider credentials are optional. Without them, the UI, bundled scene, station switching, player, and Focus Block timer still work.
The identity running the app needs bedrock:InvokeModel plus bucket-scoped permissions for s3:GetObject, s3:PutObject, s3:DeleteObject, s3:DeleteObjectVersion, and s3:ListBucketVersions. Use a role or profile scoped to the station bucket rather than an administrator identity.
For this project I included infrastructure as code with SAM to help setup the AWS parts. It's also included in the repo.
Open http://127.0.0.1:8231. You should see the station UI with the bundled placeholder scene.
Do not add NUXTPUBLIC to these names. Nuxt exposes public runtime configuration to browser code.
Keep STATIONBINDHOST on loopback unless you need remote control. For Stream Deck access from another machine, bind to a private VPN interface address, never 0.0.0.0 or a public IP, and set a long random NUXTCONTROLTOKEN. The server refuses a non-loopback binding without that token. Put provider calls behind Nuxt server routes
The browser should call your application. Compile & Chill keeps provider credentials in Nuxt runtimeConfig and places provider code under server/api/ and server/utils/.
This boundary gives you one place to validate requests, clamp paid parameters, redact signed URLs, and translate provider errors into useful HTTP responses.
You can inspect the complete routes in server/api. Generate a scene with Amazon Bedrock
Authenticate with your AWS profile first. This example uses AWS IAM Identity Center:
The image route validates the station mode, visual style, developer presentation, and optional seed. It then calls generateStationScene() in server/utils/station-generation.ts.
The server normalizes the seed before constructing the payload. This matters because Number(undefined) becomes NaN, and JSON serializes NaN as null. Stable Image Ultra expects an integer.
The prompt also ties visual style to output type. Static scenes use a realistic style. Animated scenes use a clearly illustrated 2D style so the source is visibly non-photorealistic. I added that distinction after a provider's person-likeness classifier refused one of the illustrated anchors.
Checkpoint: restart the app, open Visual settings, choose Realistic static, and generate one scene. If the model is unavailable in the configured region, the route returns the provider error and model ID instead of silently switching models. Add looping music with ElevenLabs
The UI sends a 60-second duration, and the server should reject or normalize nonnumeric input before applying its 10-to-60-second bounds. This hardened version avoids sending null to the provider if another client calls the route with an invalid value:
