🐶 nixos guide 4 fishy by ethie n packet~ :3

hiiiii cara!!!! this is a step-by-step guide 4 installing nd configuring nixos from scratch, using all da silly lil things i like 2 use like flakes, flake-parts, disko, n agenix,, so ur not just startin from weird -ahh defaults!!!

we tried 2 make this nice 4 someone who maybe doesnt install operating systems every day bcuz u have a life,,,,,,, so we added little expandable sections like u asked 4 dat explain what were actually doing at each step nd how the pieces of an operating system fit together in the context of nixos!! :33

table of contents

0 before u start

ur gonna need:

wtf is an operating system

k so an operating system is the code that sits between ur hardware (cpu, ram, disk, wifi card, evil nvidia card that never works right w linux, etc) and the programs u actually wanna run (browser, terminal, epic poggers gatcha titty games, whatever,,)

it does a few big important things:

nixos is special™ cuz instead of havin config files all over /etc like a normal linux distro, the entire system is configured in one (or a few) nix files. change th file, "rebuild", and ur system is exactly what u described. its like ... infrastructure-as-code but for ur laptop.... or like, its like,, instead of like trying to change things in ur finished cake u tweak the recipe then hit "bake" again yk


1 get the iso

OK LETS DO THIS SHIIIT

grab the latest nixos iso from nixos.org/download. u want the minimal iso (not the graphical one,,, we're doing this ourselves! we smart as hell in this bitch)

flash it 2 a usb

on linux:

dd if=nixos-25.11-*.iso of=/dev/sdX bs=4M status=progress && sync

replace /dev/sdX with ur actual usb device (lsblk 2 find it. pick right or u go to "i wiped my hard drive" jail). on windows use rufus. its a weird ahh program but it works

if ur using a vm, just attach the iso as a cdrom and boot from it. no usb needed!

2 boot it

plug in the usb, reboot, and pick it from ur boot menu (usually f12 or f2 or del or something depending on ur pc. i just spam all of em as it boots). u should land at a root shell that looks scary n intimidating.

first things first: set up networking

the installer needs internet. if ur on ethernet (heheheh) it probably just works. if ur on wifi:

# scan for networks
iwctl

# inside iwctl:
station wlan0 scan
station wlan0 get-networks
station wlan0 connect "YourNetworkName"
exit

verify it works:

ping -c 3 nixos.org
what happens when a computer boots

heres the chain of events when u press the power button:

  1. firmware (uefi/bios): tiny software baked (ok fine it gets updates so not RLY baked) into a chip on motherboard. it inits ur hardware and looks for a bootloader on a bootable device.
  2. bootloader: lives on a small partition (efi system partition for uefi systems). its job is 2 find the kernel, load it into ram, and start it.
  3. kernel: this is what Linux is!!! it detects all ur hardware, loads drivers, mounts the root filesystem, and starts process #1 (the init system).
  4. init system (systemd 4 us): reads its config and starts all the services that make the system usable: networking, sound server, display manager, ssh, etc.
  5. login prompt: the system is up and waiting for u yyyyyyay

right now ur in step 5,,, the nixos live environment is a full linux system running from ram, and we're about 2 set up steps 1-4 on ur actual disk.


3 partition ur disk with disko

this is the part where we lay out how ur disk will be organized. traditionally on nixos u'd do this manually with fdisk + mkfs + mount... but we're using disko instead, which lets u declare ur partition layout in a nix file and apply it in one command :3

what is a partition / filesystem n why do we need them

a disk is just a big ocean of bytes. partitions are how we carve up that bucket into sections with different labels!!

on a modern uefi nixos system u typically want:

each partition gets a filesystem (ext4, btrfs, etc) which is the format for organizing files and directories inside that partition. think of it like the filing system in one drawer of a filing cabinet,,

why disko? cuz doing this manually is error-prone and annoying. disko lets u declare "i want these partitions at these sizes with these filesystems" and it does the rest. and since its nix, u can reproduce ur exact disk layout on another machine just by copying the file. no swimming upstream trying 2 remember what u typed into fdisk last time.

find ur disk

lsblk

look for the disk u wanna install 2. it'll be something like /dev/nvme0n1 or /dev/sda. remember it 4 the next step.

everything on that disk will be erased. make sure u have the right one. double check. triple check. dont go for the first worm u see floatin aroun without checkin for hooks.

write a disko config

create a file called disko.nix n dump something like this into it


{
  disko.devices = {
    disk = {
      main = {
        # !!! change this 2 ur actual disk !!!
        device = "/dev/whhateverrrrrr";
        type = "disk";
        content = {
          type = "gpt";
          partitions = {
            esp = {
              name = "ESP";
              size = "512M";
              type = "EF00";
              content = {
                type = "filesystem";
                format = "vfat";
                mountpoint = "/boot";
                mountOptions = [ "umask=0077" ];
              };
            };
            root = {
              name = "root";
              size = "100%";
              content = {
                type = "filesystem";
                format = "ext4";
                mountpoint = "/";
              };
            };
          };
        };
      };
    };
  };
}
why ext4 and not btrfs / zfs

ext4 is the safe default. its mature, fast, well-supported, and doesnt have surprises. for a first nixos install its a great choice.

btrfs gives u snapshots (can roll back ur whole system), compression (saves disk space), and subvolumes (organize root/home/nix separately). nixos works great with btrfs and many people use it. the tradeoff is its Complicated

zfs is amazing but is also Complicated. its great for servers but overkill for a first desktop install imo

if u want btrfs or zfs, ask Somebody Else. im just a girl and idk complicated things like that!!!!

apply the disko config

from the live environment, run:

# get git so we can use disko! nix-shell (u wont use this ever again) is a command that lets u temporarily install n make available any package Nix can support.
nix-shell -p git

# now format and mount the disk! i know this command is long n stupid but itll  b easier to run things later.
# `sudo` runs nix as the root user.
# `--extra-experimental-features "nix-command flakes` enables the `nix whatever` command, and "flakes", two nix features that EVERYONE uses but are still TECHNICALLY in beta after being available for yeaaaaaaaaaaaaaars T_T
# `run github:nix-community/disko` downloads n runs whatever program is defined in the file `flake.nix` in the github repo `nix-community/disko`
# `-- --mode disko ./disko.nix` passes the `--mode disko disko.nix` arg to disko, which tells it to run the file u wrote!
sudo nix \
  --extra-experimental-features "nix-command flakes" \
  run github:nix-community/disko -- \
  --mode disko ./disko.nix

this will partition the disk, format each partition with the right filesystem, n mount everything at the right places under /mnt

u can check it worked ezpz by runnin

df -h | grep mnt

u should see /mnt (root) and /mnt/boot (esp).


4 write ur flake.nix

ok YAY FLAKE TIME!!! ik ur a fish so u dont rly know what a snowflake is but maybe one time u went to the surface n saw one..... while itwa s snowing,,

a flake is the entry point for ur entire nixos system config. it declares where 2 find all ur dependencies (nixpkgs, disko, home-manager, agenix, whatever) and wires them 2 ur system config.

what is a flake / why flakes

ouuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuugh.

a flake is a nix file that has inputs (other flakes u depend on (usually just nixpkgs for u for now)) and outputs (what those inputs produce,,, in ur case, a nixos system configuration).

b4 flakes, nix used channels, which were like pinned urls that would silently update... like what version of Nixpkgs they pointed to was not written down anywhere.. so they were mutable state on ur system, which is kinda the opposite of what nix is about.. since like whats the point of all this declarative stuff if u can run the same command and get a different output???? flakes fix this:

oh and were gonna use flake-parts, its a framework that makes writing flakes way nicer. instead of one giant outputs = { nixpkgs, ... }: { ... } block, flake-parts lets u throw it into lil modules. drops a LOTTA boilerplate

like ok, raw flakes = just da sea n u gotta find all ur different foods,, its all there but takes a bunch a work. flake-parts = fish food w everything u need in once place!!!!!!

we'll put our flake in /mnt/etc/nixos (cuz this is where the installer expects it).

sudo mkdir -p /mnt/etc/nixos
cd /mnt/etc/nixos

flake.nix

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";

    flake-parts.url = "github:hercules-ci/flake-parts";

    disko.url = "github:nix-community/disko";
    disko.inputs.nixpkgs.follows = "nixpkgs";

    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";

    agenix.url = "github:ryantm/agenix";
    agenix.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = {
    flake-parts,
    nixpkgs,
    ...
  } @ inputs:
    flake-parts.lib.mkFlake { inherit inputs; } {
      systems = [ "x86_64-linux" "aarch64-linux" ]; # idk if u use arm or x86, u can delete one, or not, nix wont build the one u dont need!

      flake.nixosConfigurations = {
        # replace "fishbox" with ur hostname u get to pick this <3!! 
        fishbox = nixpkgs.lib.nixosSystem {
          specialArgs = { inherit inputs; };  # magic line i dont rly understand but i think it lets u use ur other flake inputs inside ur modules
          modules = [
            ./configuration.nix
            ./hardware-configuration.nix
            inputs.disko.nixosModules.disko
            inputs.home-manager.nixosModules.home-manager
            inputs.agenix.nixosModules.default
            {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              # change this 2 ur username!!
              home-manager.users.fishy = import ./home.nix;
            }
          ];
        };
      };
    };
}
what do all these inputs do

the follows stuff means "use the same nixpkgs as me instead of fetching ur own copy." saves space n also having like two slightly diff versions of every dep is scary >,>


5 write ur system configuration

now we write the actual nixos system config. this is where u tell nixos what packages 2 install, what services 2 run, what timezone ur in, etc.

what parts of the os are we configuring here

a nixos configuration.nix touches basically everything in user space (ur da user. dis is ur space ;3)

all of these are nix options~!! configuration.nix is just a nixos module that sets a bunch of them.

configuration.nix

{ config, inputs, ... }:

{
  #### setup for booting da system

  # use systemd-boot (nice n clean :3)
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  # limit boot entries so u dont have 8 billion diff versions in ur bootloader
  boot.loader.systemd-boot.configurationLimit = 15;

  # disable the boot editor (stop someone from editing
  # boot params at the boot screen without a password which would let em get in as root lol)
  boot.loader.systemd-boot.editor = false;

  # copy kernels 2 /boot so the system can boot even if
  # /nix/store gets messed up (it happens sometimes,,)
  boot.loader.generationsDir.copyKernels = true;

  # the kernel,,, usually the default is fine!
  # boot.kernelPackages = pkgs.linuxPackages_latest;

  #### setup ur network

  networking.hostName = "mybox"; # change me to da same thing u set earlier in flake.nix!
  networking.networkmanager.enable = true; # easy wifi/ethernet ;3
/
  ##### timezone n shit

  time.timeZone = "America/New_York";
  i18n.defaultLocale = "en_US.UTF-8";

  ##### user setup!

  users.users.fishy = { # change me!
    isNormalUser = true;
    # wheel means u can use sudo, networkmanager means u can config wifi
    extraGroups = [ "wheel" "networkmanager" ];
    #
    # for the first install we use initialPassword.
    # after step 8 (agenix) well switch to hashedPasswordFile
    # and delete this!
    #
    initialPassword = "changemelater";
  };

  #### desktoppp (wayland!)

  # yes, its 2026, we use wayland :3
  # the "xserver" module name is.. ignore that.,,,
  # gnome runs on wayland by default when its available.
  # we explicitly tell gdm 2 use wayland just 2 be clear.
  services.xserver.enable = true; # needed by the gnome module (legacy name)
  services.xserver.desktopManager.gnome.enable = true;
  services.xserver.displayManager.gdm.enable = true;
  services.xserver.displayManager.gdm.wayland = true; # <- this is the important bit

  # wayland portal stuff (screen sharing, file picker, etc)
  xdg.portal.enable = true;
  xdg.portal.extraPortals = with pkgs; [
    xdg-desktop-portal-gnome
  ];

  # sound (pipewire. were enabling backcompat for programs that dont have explicit pipewire support)
  hardware.pulseaudio.enable = false;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
  };

  #### packagesss

  # system-wide packages (available 2 all users)
  environment.systemPackages = with pkgs; [
    git
    vim # or nano or wtf ever
    curl
    wget
    inputs'.agenix.packages.default
  ];

  #### nix settings

  # flakes + nix-command: required 4 our setup, this is so u dont have to pass these args every time u run a command
  nix.settings.experimental-features = [ "nix-command" "flakes" ];

  # no channels! we use flakes 4 everything.
  # channels are mutable state that drift over time,
  # the opposite of what we want
  nix.channel.enable = false;

  # dedupe the store on build (saves disk space)
  nix.settings.auto-optimise-store = true;

  # dont let flakes set nix settings without asking.
  # this is a security thing: a malicious flake could
  # set accept-flake-config = true in its own flake.nix
  # and then do whatever. say no 2 strangers :3
  nix.settings.accept-flake-config = false;

  # keep building even if one derivation fails.
  # nice when ur building a bunch of stuff and walk away,,
  # at least the other stuff finishes
  nix.settings.keep-going = true;

  # auto-free disk space: if less than ~5gb left,
  # free up to ~20gb by deleting old stuff
  # (values are in bytes: 5*1024*1024*1024 = 5368709120)
  nix.settings.min-free = 5368709120;
  nix.settings.max-free = 21474836480;

  # warn-dirty = false: dont nag us when we edit files
  # in our flake directory without committing first
  nix.settings.warn-dirty = false;

  # garbage collection, free old generations automatically
  nix.gc = {
    automatic = true;
    dates = "weekly";
    options = "--delete-older-than 7d";
  };

  #### ssh (needed 4 agenix)

  # this generates host keys at /etc/ssh/ on first boot,
  # which agenix uses 2 decrypt secrets.
  services.openssh = {
    enable = true;
    hostKeys = [
      {
        type = "ed25519";
        path = "/etc/ssh/ssh_host_ed25519_key";
      }
    ];
  };

  #### firewall

  networking.firewall.enable = true;
  # networking.firewall.allowedTCPPorts = [ 22 ]; # ssh!

  #### dont change this! its like which version of config ur config is, 
  # its a whole thing to update, and u basically never should change this unless u rlylllllll need to 
  system.stateVersion = "25.11"; # matches ur nixpkgs channel

  # let home-manager manage itself
  home-manager.extraSpecialArgs = { inherit inputs; };
}

hardware-configuration.nix

this file is auto-generated by the installer,,, it contains the filesystem mounts and hardware-specific kernel modules. do not write this by hand. the nixos-generate-config command in the next step will create it 4 u. just make sure the file exists after that step.

why does hardware-configuration exist separately

cuz hardware is, well,,, hardware-specific. every machine has different drives, different network cards, different cpu features. nixos can auto-detect most of this and generates a file with:

keeping it separate means u can share configuration.nix between machines and only swap out hardware-configuration.nix per box. like how every salmon swims upstream but they all go up different rivers. or sometrhing.

home.nix

ur user-level config done thru home-manage!

{ pkgs, ... }:

{
  home.username = "fishy"; # change meeee
  home.homeDirectory = "/home/fishy"; # change me etoooo
  home.stateVersion = "25.11";

  # user packages,, just 4 u <3
  # if a package is available under programs.whatever, config it there usually
  home.packages = with pkgs; [
    firefox
    ghostty
    ripgrep
    bat
    eza
    starship
    bottom
  ];

  # git config
  programs.git = {
    enable = true;
    userName = "ur name on github or w/e";
    userEmail = "cara@fishy.com";
  };

  # idk u could do like nice bash aliases, or zsh or whatev erese sleee
  programs.bash = {
    enable = true;
    shellAliases = {
      ll = "ls -al";
    };
  };

  # let home manager install and manage itself
  programs.home-manager.enable = true;
}

6 install

ok we're almost there!!!! 2 more commands 2 go awaaaaaa :333

generate hardware config

# this makes /mnt/etc/nixos/hardware-configuration.nix
sudo nixos-generate-config --root /mnt

now check that hardware-configuration.nix exists and looks kinda vaguely sane

cat /mnt/etc/nixos/hardware-configuration.nix
and btw because u used disko, the generated file should already have the right fileSystems entries. if something looks wrong (like missing mountpoints), double-check ur disko.nix was applied correctly.

do the install!!! YAY

# build the whole system and install it
sudo nixos-install --root /mnt --flake /mnt/etc/nixos#hostname_u_picked

this will take a while (downloading + building everything). go swim around or something :3

when it asks 4 a password, thats setting the root password. u can also just leave it blank and rely on sudo from ur user account.

after it finishes, reboot:

sudo reboot

pull out th usb when it reboots. if everything went well, u should see a boot menu and then the nixos login screen!!!! u did it!!!!!

what nixos-install actually does under the hood

nixos-install does a bunch of stuff:

  1. evaluates ur flake it reads flake.nix, resolves all inputs, and builds the full system closure (a giant derivation (derivation is like.. a big Output, something that Is Derived) containing every single file ur system needs)
  2. copies the closure 2 /mnt/nix/store this is the nix store where all packages live. its content-addressed and read-only, which is what makes nixos reproducible.
  3. creates the system profile a symlink at /mnt/nix/var/nix/profiles/system pointing at ur built closure. this is what the bootloader entry points 2.
  4. installs the bootloader writes the boot entry 2 the esp so u can actually boot into the system.
  5. sets root password

the #hostname_u_picked in the flake url tells it 2 use the nixosConfigurations.hostname_u_picked output from ur flake. u named urs something else so make sre u changed it !!


7 post-install stuff

yayyyyyy u have nixos now!!!!!! >w< a few things 2 do after ur first boot

log in and change ur password

u set initialPassword = "changeme" or whatever i told u to make it,, right? change it

passwd

update ur system

# update flake inputs (this updates flake.lock!)
nix flake update /etc/nixos

# rebuild the system with new inputs
sudo nixos-rebuild switch --flake /etc/nixos
what is nixos-rebuild switch

nixos-rebuild switch is how u apply changes 2 ur running system. it,, evaluates ur flake / config, builds the new system closure, creates a new generation (a numbered snapshot of ur system), activates the new config (starts/stops services, reloads systemd units, etc), adds the generation 2 the boot menu (so u can roll back if something breaks!)

nixos-rebuild test does the same but doesnt add a boot entry,,, good for testing risky changes. nixos-rebuild boot adds the boot entry but doesnt activate (takes effect on next reboot).

if something goes wrong, just pick the previous generation from the boot menu!!!!!1 and ur back where u were!!!!!!!!!!! this is one of the best things about nixos,,, u can always roll bac!! its so cool its like,... how to explain to a fish,, a tide pool, even if u splash around a bunch n mess up, theres no wavess big enough thatll wash u out to sea :3 u get to hang otu in ur little pool

set up ur git repo (optional but recommended)

cd /etc/nixos
git init
git add .
git commit -m "initial nixos config"

push it 2 github or wherever so u have a backup and can clone it on other machines :3


8 secrets with agenix

k so heres the thing, nixos is declarative, which is great, but that means everything in ur config is in the nix store and the nix store is world-readable. so if u put a password in ur configuration.nix, anyone on the machine can read it. which is cringe as fuck.

agenix fixes this!!! it encrypts ur secrets with age encryption (this is just like cool modern pgp) (using ur machines SSH host keys as the encryption keys), stores the encrypted files in the nix store (which is fine cuz theyre encrypted), and decrypts them at boot time into /run/agenix/ (which is in ram!!! and not world-readable!!).

wwhat about sops-nix

why do you know whta that is??

for a first nixos install, agenix simpler. if u need more key types or like anti tamper, sops-nix is there 4 u. but ive neve rused it. agenix is fine.

htheres like a setup catch though, agenix decrypts secrets using the SSH host key at /etc/ssh/ssh_host_ed25519_key. but that key doesnt exist until the machine has booted at least once (its generated on first boot by the openssh service we enabled in configuration.nix). so agenix cant work on the very first install, whic his why were doing it now.

thats why we did initialPassword = "changeme". its a temporary thing! once uv booted and the SSH host keys exist, u can set up agenix and then remove that line.

step 8a: get ur machines public key

after first boot, ur machine has generated its SSH host key. grab the public key:

sudo cat /etc/ssh/ssh_host_ed25519_key.pub

itll look something like ssh-ed25519 AAAAC3NzaC1... root@mybox. copy that whole line.

step 8b: create the secrets.nix file

secrets.nix is a mapping file that tells the agenix CLI which public keys 2 encrypt each secret for. its not imported by ur nixos config, its just used by the agenix command-line tool.

mkdir -p /etc/nixos/secrets

create /etc/nixos/secrets/secrets.nix:

let
  # ur machines SSH host public key (from step 8a)
  whatever_hostname = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... root@whatever_hostname";

  # ur personal SSH key (optional, lets u decrypt on another machine, u should prolyly do it tho)
  # fishy = "ssh-ed25519 AAAAC3... lalala@whatever";

  systems = [ whatever_hostname ];
  # users = [ fishy ];
in
{
  # each entry maps an .age file 2 the keys that can decrypt it!!!
  "fishy-password.age".publicKeys = systems;
  # "fishy-password.age".publicKeys = systems ++ users; # if u added a user key do dis
}
why is secrets.nix separate from the nixos config

secrets.nix is only used by the agenix CLI tool 2 know which public keys 2 encrypt 4. its never imported into ur nixos configuration. the nixos module just needs the .age files and the age.secrets declarations in configuration.nix.

this is a bit confusing at first, but,, but it makes sense, cuz the encryption happens offline (on whatever machine ur editing secrets on), and the decryption step happens on the target machine at boot. theyre separate processes that just share the same .age files!!

step 8c create the encrypted password

first generate a hashed password. u need the hash, not the plaintext, so..

mkpasswd -m sha-512

itll prompt u 4 a password and print out a long hash starting with $6$. copy that.

now make anencrypted secret:

cd /etc/nixos/secrets
  # the nix run command is so cool. just run some piece of code w all its deps from a github repo!!!
nix run github:ryantm/agenix -- -e fishy-password.age

this opens ur editor. paste the hashed password (that long $6$... string) and save. agenix encrypts it with the public keys from secrets.nix and saves it as you-password.age.

step 8d: tell nixos about the secret

add this 2 ur configuration.nix, inside the existing users.users.you block or nearby:

  # agenix secrets
  age.secrets.fishy-password = {
    file = ./secrets/fishy-password.age;
  };

  users.users.you = {
    isNormalUser = true;
    extraGroups = [ "wheel" "networkmanager" ];
    # use the agenix secret instead of initialPassword!
    hashedPasswordFile = config.age.secrets.fishy-password.path;
  };

and now u can remove the initialPassword = "whatever"; line! u dont need it anymore cuz urusing da encyrpted one :3

step 8e: rebuild and verify

cd /etc/nixos
sudo nixos-rebuild switch --flake .#whatever_ur_hostname_is

after the switch u can check that the secret worked,,

sudo ls /run/agenix/

u should see fishy-password in there.

and verify ur user account still works by opening a new terminal and running su - fishy or just logging out and back in with ur password. if its fucked u can always roll back in the bootloader :D

more abt agenix

when nixos rebuilds/boots with agenix,,,

the encrypted .age file gets copied into the nix store which is safe cuz its encrypted

agenix runs like a script during switch or boot that uses the machines SSH host private key (/etc/ssh/ssh_host_ed25519_key) 2 decrypt the .age file the plaintext secret is written 2 /run/agenix/<name>

ur nixos config can reference it via config.age.secrets.<name>.path

the secret only exists in ram, not on disk, and is only readable by the owner/group u specify. way better than having it sitting in the nix store 4 anyone 2 read.

if u add more secrets later (wifi passwords, api keys, whatever), just add the entry 2 secrets.nix, encrypt with agenix -e, write age.secrets.whatever in config, rebuild

commit everything :D

cd /etc/nixos
git add .
git commit -m "add awesome encrypted files!"

the .age files are safe 2 commit cztheyre encrypted! the secrets.nix file only has public keys, so thats fine 2 commit too.


9 ok now what

ok u have a working nixos system with proper secrets management now!!!! here are some things u might wanna look at

okand so the golden rule is that !!! if u changed something manually (edited a file in /etc, installed a package with nix-env (dont od this pls ), etc), it will be lost on the next rebuild,, always make changes in ur nix config and rebuild. that way ur system is always declarative and reproducible. the nix store is the ocean w all the fishy,, ,,, everything outside it is a puddle that evaporates. after the tide recedes..
OK BYE CARAA ILYYYYYYYY

made with paws <3 by ethie n packet 4 fishy~! :3