Sending custom emails programmatically in Magento 2 involves creating an email template, configuring email transport, and writing PHP code to send the email. Here’s how you can do it step by step:

1. Create the Email Sending Logic

You can place your email-sending logic in any execute function. Here’s an example using an execute function:
use Exception;
use Magento\Framework\App\Area;
use Psr\Log\LoggerInterface;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Store\Model\StoreManagerInterface;

class SendMail
{
    private LoggerInterface $logger;
    private TransportBuilder $transportBuilder;
    private StateInterface $state;
    private StoreManagerInterface $storeManager;

    public function __construct(
        LoggerInterface       $logger,
        TransportBuilder      $transportBuilder,
        StateInterface        $state,
        StoreManagerInterface $storeManager,
    )
    {
        $this->logger = $logger;
        $this->transportBuilder = $transportBuilder;
        $this->state = $state;
        $this->storeManager = $storeManager;
    }
    public function execute()
    {
        $this->state->suspend();
        try {
            $store = $this->storeManager->getStore()->getId();
            $transport = $this->transportBuilder
                ->setTemplateIdentifier('template_id')
                ->setTemplateOptions([
                    'area' => Area::AREA_FRONTEND,
                    'store' => $store,
                ])
                ->setTemplateVars([
                    'text' => 'magekwik',
                ])
                ->setFrom([
                    'name' => 'sender name',
                    'email' => 'sender@example.com',
                ])
                ->addTo('recipient@example.com')
                ->getTransport();

            $transport->sendMessage();
            $this->state->resume();

            $this->logger->info('Email sent successfully.');
        } catch (Exception $e) {
            $this->logger->error('Error sending email: ' . $e->getMessage());
        }
    }
}

2. Register the Email Template

Create the app/code/Vendor/Module/etc/frontend/di.xml file:
 
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
    <template id="template_id" label="label" file="custom_email_template.html" type="html" module="Vendor_Module" area="frontend"/>
</config>

3. Create the Email Template

Create the app/code/Vendor/Module/view/frontend/email/custom_email_template.html file:
 
<!--@subject enter subject @-->
{Error in template processing}
<h3>Hello <b>{{var text|raw}}</b></h3>
{Error in template processing}

Summary

Following these steps, you can programmatically send custom emails in Magento 2. The example includes an email template, an execute function for sending emails and integration with Magento's email system. You can modify the template and helper to fit your specific needs, such as adding more variables or customising the email content.