How to create creditmemo for order item programmatically in magento 2?

We can create credit memo for the specific item based on below way in Magento 2. We need to pass some basic data to generate credit memo in Magento 2.

<?php
namespace Rbj\Credit\Controller\Adminhtml\Index;

class Creditmemo extends \Magento\Backend\App\Action
{
	public function __construct(
	    \Magento\Backend\App\Action\Context $context,
	    \Magento\Sales\Model\Order\Email\Sender\CreditmemoSender $creditmemoSender,
	    \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
	) {
	    $this->creditmemoSender = $creditmemoSender;
        $this->creditmemoLoader = $creditmemoLoader;
	    parent::__construct($context);
	}

	/* Generate Credit memo of item
     * Save creditmemo
     *
     */
	public function execute()
	{
	   	$orderId = 1; // order entity_id
        $creditMemoData = [];
        $creditMemoData['do_offline'] = 1;
        $creditMemoData['shipping_amount'] = 0;
        $creditMemoData['adjustment_positive'] = 0;
        $creditMemoData['adjustment_negative'] = 0;
        $creditMemoData['comment_text'] = 'comment_text_for_creditmemo';
        $creditMemoData['send_email'] = 1;
        //$creditMemoData['refund_customerbalance_return_enable'] = 0; // for Magento commerce
        $orderItemId = 10; // pass order item id
        $itemToCredit[$orderItemId] = ['qty'=>1];
        $creditMemoData['items'] = $itemToCredit;

	    try {

        	$resultRedirect = $this->resultRedirectFactory->create();
	        $this->creditmemoLoader->setOrderId($orderId); //pass order id
	        $this->creditmemoLoader->setCreditmemo($creditMemoData);

	        $creditmemo = $this->creditmemoLoader->load();
	        if ($creditmemo) {
	            if (!$creditmemo->isValidGrandTotal()) {
	                throw new \Magento\Framework\Exception\LocalizedException(
	                    __('The credit memo\'s total must be positive.')
	                );
	            }

	            if (!empty($creditMemoData['comment_text'])) {
	                $creditmemo->addComment(
	                    $creditMemoData['comment_text'],
	                    isset($creditMemoData['comment_customer_notify']),
	                    isset($creditMemoData['is_visible_on_front'])
	                );

	                $creditmemo->setCustomerNote($creditMemoData['comment_text']);
	                $creditmemo->setCustomerNoteNotify(isset($creditMemoData['comment_customer_notify']));
	            }

	            $creditmemoManagement = $this->_objectManager->create(
	                \Magento\Sales\Api\CreditmemoManagementInterface::class
	            );
	            $creditmemo->getOrder()->setCustomerNoteNotify(!empty($creditMemoData['send_email']));
	            $creditmemoManagement->refund($creditmemo, (bool)$creditMemoData['do_offline']);

	            if (!empty($creditMemoData['send_email'])) {
	                $this->creditmemoSender->send($creditmemo);
	            }

	            $this->messageManager->addSuccess(__('You created the credit memo.'));
	            $this->_getSession()->getCommentText(true);
	            $resultRedirect->setPath('sales/order/view', ['order_id' => $orderId]);
                return $resultRedirect;
	        }
	    } catch (\Magento\Framework\Exception\LocalizedException $e) {
	        $this->messageManager->addError($e->getMessage());
	    } catch (\Exception $e) {
	        $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
	        $this->messageManager->addError(__('We can\'t save the credit memo right now.'));
	    }
	    $this->_redirect('adminhtml/*/');
	}
}

By above way, We can create credit memo in magento 2.

We have pass do_offline = 1 means we have generated credit memo offline. If you want to refund shipping amount pass shipping amount value to shipping_amount field.

You can set adjustment_positive and adjustment_negative value if you want.

if you want to notify customer, set comment_text field in above function.

Pass orderItemId of order item and set qty to refund.

Example,

$orderItemId = 10; // pass order item id
        $itemToCredit[$orderItemId] = ['qty'=>1];
        $creditMemoData['items'] = $itemToCredit;

Order item id is 10 and qty to refund is 1, you can pass multiple item using foreach loop in above syntax.