臨時
臨時

rinji.dev — a provisional workshop for temporary code

things that were never meant to last but somehow persist

the philosophy of temporary code

Every piece of software begins as a provisional solution. The first commit is always a guess — an approximation, a sketch drawn in the dark. Most developers treat this impermanence as a problem to solve. Here, we treat it as a feature.

Temporary code is honest code. It doesn't pretend to be the final answer. It wears its provisionality like a badge — this works for now, and that's enough. The Japanese concept of 臨時 (rinji) captures this perfectly: something ad-hoc, something that exists because the moment demanded it.

provisional.js javascript
const createTemporary = (lifespan) => {
  // nothing here is permanent. that's the point.
  return {
    born: Date.now(),
    expires: Date.now() + lifespan,
    decompose() {
      return `i lived for ${lifespan}ms`;
    }
  };
};

In the forest, nothing is wasted. Dead wood feeds mushrooms. Fallen leaves become soil. In software, temporary code feeds the next iteration — the quick fix reveals the shape of the real solution. The provisional illuminates the permanent.

the workshop floor

Here is where the work happens. Rough-hewn tools, provisional solutions, code that grows like lichen on stone. Each specimen below is a living fragment — functional, temporary, ready to decompose into something better.

specimen 001: the ephemeral cache

A cache that knows it will expire. It doesn't fight entropy — it embraces it. Each entry carries a timestamp of its own mortality, counting down to the moment it returns to the void.

ephemeral-cache.js javascript
class EphemeralCache {
  #store = new Map();

  set(key, value, ttl = 30000) {
    // every entry knows when it dies
    const entry = {
      value,
      born: Date.now(),
      deathAt: Date.now() + ttl,
      isAlive() {
        return Date.now() < this.deathAt;
      }
    };
    this.#store.set(key, entry);
    setTimeout(() => this.#store.delete(key), ttl);
  }

  get(key) {
    const entry = this.#store.get(key);
    return entry?.isAlive() ? entry.value : undefined;
  }
}

specimen 002: the decay observer

A watcher that monitors the lifecycle of temporary resources. When something expires, it doesn't just clean up — it records the decomposition, preserving the memory of what was temporary.

decay-observer.js javascript
function observeDecay(target, onDecompose) {
  const proxy = new Proxy(target, {
    get(obj, prop) {
      if (prop === '__expired') return obj.__expired;
      if (obj.__expired) {
        onDecompose(prop, obj[prop]);
        return undefined;
      }
      return obj[prop];
    }
  });
  // schedule the inevitable
  setTimeout(() => {
    target.__expired = true;
  }, target.ttl || 60000);
  return proxy;
}

ephemeral patterns

Software patterns are usually taught as permanent solutions — structures carved in stone. But the most useful patterns are provisional. They emerge from necessity, serve their purpose, and gracefully decompose when the context changes.

the provisional singleton

A singleton that knows it shouldn't exist forever. It creates itself when needed and dissolves after a period of inactivity. Like a mushroom that fruits after rain and retreats underground when the sun returns.

provisional-singleton.js javascript
let instance = null;
let decayTimer = null;

function getProvisional(config) {
  if (!instance) {
    instance = createInstance(config);
  }
  // reset the decay clock
  clearTimeout(decayTimer);
  decayTimer = setTimeout(() => {
    instance.cleanup();
    instance = null;
    // returned to the forest floor
  }, config.idleTimeout || 300000);
  return instance;
}

The pattern above embodies rinji thinking: create what you need, use it while it serves, let it go when it's done. No clinging. No premature optimization. Just honest, temporary code.

the compost heap

Every temporary solution eventually returns to the soil. The cache entries expire. The provisional singletons dissolve. The quick fixes get replaced by slower, more considered implementations. And that's exactly how it should be.

In the forest, decomposition is not failure — it's the engine of renewal. Dead wood feeds the mycorrhizal network. Fallen code feeds the next refactor. The cycle continues, each iteration composting the last into richer ground.

The specimens you've encountered here are not permanent. They were never meant to be. They are rinji — provisional, ad-hoc, beautifully temporary. Use them. Modify them. Let them decompose when the time comes. Write new ones in their place.

nothing here is permanent. that's the point.