Monero transactions are much more than some simple data that is signed with a private key. You need outputs to spend, mixin outputs from the blockchain, lot's of math for RingCT etc. This is one of the reasons the RPC interfaces (daemon and wallet) exist. These can be called by any language which can call a URL and create/parse JSON.
If you use the wallet RPC, you can call transfer with
get_tx_metadata: true and
do_not_relay: true to get
tx_metadata which can later be broadcast with submit_transfer (or of course do this all in one step with just transfer, without the aforementioned parameters).
If you just want to understand the math that goes into RingCT, read the MRL-0005 paper, or the broader Zero to Monero book. And if you just want to understand the structure of a transaction, see the Monero source code which defines the structures used.