It's important to understand that the "universal code" evolved from earlier, simpler codes.
The genetic code, understood as the specific assignment of amino acids to nucleotide triplets, might have preceded the existence of translation.
Amino acids were utilized as cofactors by ribozymes in a metabolically complex RNA world. Specific charging ribozymes linked amino acids to corresponding RNA handles, which could basepair with different ribozymes, via an anticodon hairpin, and so deliver the cofactor to the ribozyme.
Growing of the ”handle’ into a presumptive tRNA was possible while function was retained and modified throughout.
A stereochemical relation between some amino acids and cognate anticodons/codons is likely to have been important in the earliest assignments.
Trends in Genetics
Volume 15, Issue 6, 1 June 1999, Pages 223-229
Here.
It has also been suggested that the code and the AA biosynthesis co-evolved.
A coherent pattern of evolution will be seen to emerge in which addition of a new amino acid to the code typically followed path extension, tRNA diversification to a new acceptor, expansion in synthetase specificity and selection for each synthesized protein.
The coevolution hypothesis (Wong, 1975, 1976) requires that precursors among coded amino acids entered the code before their products. In this section, the time of entry of each amino acid into the code has been estimated from the number of reactions in its biosynthetic pathway. A phased pattern of synthesis emerges, in the sense that physicochemically divergent amino acids appear at divergent stages of code evolution. This has significant implications for code evolution and the origin of life.
Evolution of the genetic code
Brian K. Davis
Progress in Biophysics & Molecular Biology 72 (1999) 157-243.
The evolution of a stop codon isn't quite so difficult to imagine if you keep in mind that the whole thing was kluged together.