How to use recursion to turn object into string?
I agree that JSON.stringify isn't the most appropriate for this problem, not just because it's slower, but also because it's a bit harder to understand. And you're also right in assuming that reduce() isn't the best tool for the job. Using a .map() reads in a much more natural way.


const convert = obj =&gt; (
  Object.entries(obj)
    .map(([key, value]) =&gt; (
      typeof value === 'string'
        ? `${key}:${value};`
        : `${key}{${convert(value)}}`
    ))
    .join('')
)

console.log(convert({
  a: {
    b: 'c',
    d: 'e'
  },
}))



When optimizing this, think about the use case. While tail-call recursion may or may not be possible, it will make the code much more difficult to read, and it really won't help. The main advantage to tail-call recursion is to save memory on the call stack, and to let a recursive function call into itself an unlimited amount of times while still using just one call-frame worth of memory on the stack. There's no practical chunk of extremely nested CSS that can be written to make tail-call optimization worth it.
In your question, speed seems to be one of your primary concerns, but I'll play a bit of devil's advocate here and ask if it really should be for this use case. How much CSS-in-JS would you need to write before any of these micro-performance improvements even become noticeable? Tens of thousands of lines? Hundreds of thousands? I would suggest just building out the library first, run some benchmarks afterwards, and find out what parts of it actually run slow. Then only worry about fixing the slower areas.