user18704: I know how to create a basic TX:
var bitcoin = require('bitcoinjs-lib')

var tx = new bitcoin.Transaction()

// Add the input (who is paying) of the form [previous transaction hash, index of the output to use]
tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31", 0)

// Add the output (who to pay to) of the form [payee's address, amount in satoshis]
tx.addOutput("THEADDRESS", 15000)

// Initialize a private key using WIF
key = bitcoin.ECKey.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")

// Sign the first input with the new key
tx.sign(0, key)

// Print transaction serialized as hex
console.log(tx.toHex())
// => 0100000001313eb630b128102b60241ca895f1d0ffca2170d5a0990e094f2182c102ab94aa000000008a47304402200169f1f844936dc60df54e812345f5dd3e6681fea52e33c25154ad9cc23a330402204381ed8e73d74a95b15f312f33d5a0072c7a12dd6c3294df6e8efbe4aff27426014104e75628573696aed32d7656fb35e9c71ea08eb6492837e13d2662b9a36821d0fff992692fd14d74fdec20fae29128ba12653249cbeef521fc5eba84dde0689f27ffffffff01983a0000000000001976a914ad618cf4333b3b248f9744e8e81db2964d0ae39788ac00000000

// You could now push the transaction onto the Bitcoin network manually (see https://blockchain.info/pushtx)

But I didn't find out how I could create a OP_RETURN transaction with bitcoinjs-lib in Node.js. Does anyone know?

user41988: For bitcoinjs-lib 3.2.0 (not latest):
bitcoinjs = require('bitcoinjs-lib');

const wif = 'private-key-of-sender-in-WIF';
const sender = 'miq6AWvTYZJ63hJfh1W7zozHAf1URDv5pS';
const unspent_txid = '8e320e71d43b130c0786cc9d50fae9ed79b953fba9bcf45070625e37120544c3';
const unspent_vout = 1;
const network = bitcoinjs.networks.testnet;
const keyPair = bitcoinjs.ECPair.fromWIF(wif,network);
const recipient = 'mwLfrTGnLNtyLWFzLfPVcmxEMcW4yaRUZA';

const txb = new bitcoinjs.TransactionBuilder(network);
const data = Buffer.from('YOUR OP_RETURN DATA HERE', 'utf8');
const dataScript = bitcoinjs.script.nullData.output.encode(data);
txb.addInput(unspent_txid, unspent_vout); // payer
txb.addOutput(recipient, Math.floor(1.88*1e8)); // payee
txb.addOutput(dataScript, 0); // OP_RETURN always with 0 value unless you want to burn coins

txb.sign(0, keyPair);

const txRaw = txb.build();
const txHex = txRaw.toHex();

// To broadcast, use local bitcoin core's `sendrawtransaction` or 3rd party service


UPDATE: with bitcoinjs-lib 5.0.2 (latest), same as above, only update the dataScript evaluation and the adding of the OP_RETURN output:
const dataScript = bitcoinjs.payments.embed({ data: [data] });
txb.addOutput(dataScript.output, 0); // OP_RETURN always with 0 value unless you want to burn coins


user72197: Here's how I was able to accomplish this with the latest bitcoinjs-lib version (5.2.0) using psbt.
const alice = bitcoin.ECPair.fromWIF(wif, bitcoin.networks.regtest);
const inputData1 = {
    hash: randomutxo.txid,
    index: randomutxo.vout,
    witnessUtxo: {script: Buffer.from(randomutxo.scriptPubKey, 'hex'), value: parseInt(randomutxo.amount*100000000)}
    };
const data = Buffer.from('YOUR OP_RETURN DATA HERE', 'utf8');
const embed = bitcoin.payments.embed({ data: [data] });
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.regtest })
    .addInput(inputData1)
    .addOutput({
    script: embed.output,
    value: 0,
    })
    .addOutput({
    address: 'bcrt1q7xp6jcgmnuvvaqzr9sdg7yjdqfftswjdqz9897',
    value: 50000,
    })
    .addOutput({
    address: 'bcrt1q7xp6jcgmnuvvaqzr9sdg7yjdqfftswjdqz9897',
    value: parseInt(randomutxo.amount*100000000)-100000,
    })
    .signInput(0, alice);

psbt.finalizeAllInputs();
const txHex = psbt.extractTransaction().toHex();


user2306: Here:
var bitcoin = require('bitcoinjs-lib')

data = new Buffer("Melons.")

var tx = new bitcoin.TransactionBuilder()
tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31", 0)
tx.addOutput("some address", 15000)
ret = bitcoin.script.compile(
  [
    bitcoin.opcodes.OP_RETURN,
    data
  ])
tx.addOutput(ret, 0)
key = bitcoin.ECPair.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")
tx.sign(0, key)
console.log(tx.build().toHex())

That should do it.
Also, if you have more than 40 bytes of data, your transaction will be non-standard.

18704: <p>I know how to create a basic TX:</p>

<pre><code>var bitcoin = require('bitcoinjs-lib')

var tx = new bitcoin.Transaction()

// Add the input (who is paying) of the form [previous transaction hash, index of the output to use]
tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31", 0)

// Add the output (who to pay to) of the form [payee's address, amount in satoshis]
tx.addOutput("THEADDRESS", 15000)

// Initialize a private key using WIF
key = bitcoin.ECKey.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")

// Sign the first input with the new key
tx.sign(0, key)

// Print transaction serialized as hex
console.log(tx.toHex())
// =&gt; 0100000001313eb630b128102b60241ca895f1d0ffca2170d5a0990e094f2182c102ab94aa000000008a47304402200169f1f844936dc60df54e812345f5dd3e6681fea52e33c25154ad9cc23a330402204381ed8e73d74a95b15f312f33d5a0072c7a12dd6c3294df6e8efbe4aff27426014104e75628573696aed32d7656fb35e9c71ea08eb6492837e13d2662b9a36821d0fff992692fd14d74fdec20fae29128ba12653249cbeef521fc5eba84dde0689f27ffffffff01983a0000000000001976a914ad618cf4333b3b248f9744e8e81db2964d0ae39788ac00000000

// You could now push the transaction onto the Bitcoin network manually (see https://blockchain.info/pushtx)
</code></pre>

<p>But I didn't find out how I could create a OP_RETURN transaction with bitcoinjs-lib in Node.js. Does anyone know?</p>
 41988: <p>For <em>bitcoinjs-lib 3.2.0</em> (not latest):</p>

<pre><code>bitcoinjs = require('bitcoinjs-lib');

const wif = 'private-key-of-sender-in-WIF';
const sender = 'miq6AWvTYZJ63hJfh1W7zozHAf1URDv5pS';
const unspent_txid = '8e320e71d43b130c0786cc9d50fae9ed79b953fba9bcf45070625e37120544c3';
const unspent_vout = 1;
const network = bitcoinjs.networks.testnet;
const keyPair = bitcoinjs.ECPair.fromWIF(wif,network);
const recipient = 'mwLfrTGnLNtyLWFzLfPVcmxEMcW4yaRUZA';

const txb = new bitcoinjs.TransactionBuilder(network);
const data = Buffer.from('YOUR OP_RETURN DATA HERE', 'utf8');
const dataScript = bitcoinjs.script.nullData.output.encode(data);
txb.addInput(unspent_txid, unspent_vout); // payer
txb.addOutput(recipient, Math.floor(1.88*1e8)); // payee
txb.addOutput(dataScript, 0); // OP_RETURN always with 0 value unless you want to burn coins

txb.sign(0, keyPair);

const txRaw = txb.build();
const txHex = txRaw.toHex();

// To broadcast, use local bitcoin core's `sendrawtransaction` or 3rd party service
</code></pre>

<hr>

<p><strong>UPDATE</strong>: with <em>bitcoinjs-lib 5.0.2</em> (latest), same as above, only update the <code>dataScript</code> evaluation and the adding of the <code>OP_RETURN</code> output:</p>

<pre><code>const dataScript = bitcoinjs.payments.embed({ data: [data] });
txb.addOutput(dataScript.output, 0); // OP_RETURN always with 0 value unless you want to burn coins
</code></pre>
 72197: <p>Here's how I was able to accomplish this with the latest bitcoinjs-lib version (5.2.0) using psbt.</p>
<pre><code>const alice = bitcoin.ECPair.fromWIF(wif, bitcoin.networks.regtest);
const inputData1 = {
    hash: randomutxo.txid,
    index: randomutxo.vout,
    witnessUtxo: {script: Buffer.from(randomutxo.scriptPubKey, 'hex'), value: parseInt(randomutxo.amount*100000000)}
    };
const data = Buffer.from('YOUR OP_RETURN DATA HERE', 'utf8');
const embed = bitcoin.payments.embed({ data: [data] });
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.regtest })
    .addInput(inputData1)
    .addOutput({
    script: embed.output,
    value: 0,
    })
    .addOutput({
    address: 'bcrt1q7xp6jcgmnuvvaqzr9sdg7yjdqfftswjdqz9897',
    value: 50000,
    })
    .addOutput({
    address: 'bcrt1q7xp6jcgmnuvvaqzr9sdg7yjdqfftswjdqz9897',
    value: parseInt(randomutxo.amount*100000000)-100000,
    })
    .signInput(0, alice);

psbt.finalizeAllInputs();
const txHex = psbt.extractTransaction().toHex();
</code></pre>
 2306: <p>Here:</p>

<pre><code>var bitcoin = require('bitcoinjs-lib')

data = new Buffer("Melons.")

var tx = new bitcoin.TransactionBuilder()
tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31", 0)
tx.addOutput("some address", 15000)
ret = bitcoin.script.compile(
  [
    bitcoin.opcodes.OP_RETURN,
    data
  ])
tx.addOutput(ret, 0)
key = bitcoin.ECPair.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")
tx.sign(0, key)
console.log(tx.build().toHex())
</code></pre>

<p>That should do it.</p>

<p>Also, if you have more than 40 bytes of data, your transaction will be non-standard.</p>
